@jscad/x3d-serializer 2.4.2 → 2.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.4.4](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/x3d-serializer@2.4.3...@jscad/x3d-serializer@2.4.4) (2023-04-30)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **x3d-serializer:** corrected color and transparency conversions ([cc99548](https://github.com/jscad/OpenJSCAD.org/commit/cc9954853c30c6a82fcd26cda686e7f51f9fa304))
12
+ * **x3d-serializer:** corrected colors, orientation of scene to Y up, and added new option for smoothing ([3444e2d](https://github.com/jscad/OpenJSCAD.org/commit/3444e2d462446694e62da71b130dfb4e56e92f82))
13
+
14
+
15
+
16
+
17
+
18
+ ## [2.4.3](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/x3d-serializer@2.4.2...@jscad/x3d-serializer@2.4.3) (2022-11-26)
19
+
20
+ **Note:** Version bump only for package @jscad/x3d-serializer
21
+
22
+
23
+
24
+
25
+
6
26
  ## [2.4.2](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/x3d-serializer@2.4.1...@jscad/x3d-serializer@2.4.2) (2022-08-21)
7
27
 
8
28
  **Note:** Version bump only for package @jscad/x3d-serializer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jscad/x3d-serializer",
3
- "version": "2.4.2",
3
+ "version": "2.4.4",
4
4
  "description": "X3D Serializer for JSCAD",
5
5
  "homepage": "https://openjscad.xyz/",
6
6
  "repository": "https://github.com/jscad/OpenJSCAD.org",
@@ -33,12 +33,12 @@
33
33
  "license": "MIT",
34
34
  "dependencies": {
35
35
  "@jscad/array-utils": "2.1.4",
36
- "@jscad/modeling": "2.10.0",
36
+ "@jscad/modeling": "2.11.1",
37
37
  "onml": "1.3.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "ava": "3.15.0",
41
41
  "nyc": "15.1.0"
42
42
  },
43
- "gitHead": "13572067545460affd53b64b3ab834a39af8c7e5"
43
+ "gitHead": "4313974b50957018d2edd010e3a251f59bea46a4"
44
44
  }
package/src/index.js CHANGED
@@ -34,7 +34,7 @@ Notes:
34
34
  const { geometries, modifiers } = require('@jscad/modeling')
35
35
  const { geom2, geom3, path2, poly2, poly3 } = geometries
36
36
 
37
- const { flatten, toArray } = require('@jscad/array-utils')
37
+ const { flatten } = require('@jscad/array-utils')
38
38
 
39
39
  const stringify = require('onml/lib/stringify')
40
40
 
@@ -48,6 +48,8 @@ const mimeType = 'model/x3d+xml'
48
48
  * Serialize the give objects to X3D elements (XML).
49
49
  * @param {Object} options - options for serialization, REQUIRED
50
50
  * @param {Array} [options.color=[0,0,1,1]] - default color for objects
51
+ * @param {Boolean} [options.smooth=false] - use averaged vertex normals
52
+ * @param {Number} [options.decimals=1000] - multiplier before rounding to limit precision
51
53
  * @param {Boolean} [options.metadata=true] - add metadata to 3MF contents, such at CreationDate
52
54
  * @param {String} [options.unit='millimeter'] - unit of design; millimeter, inch, feet, meter or micrometer
53
55
  * @param {Function} [options.statusCallback] - call back function for progress ({ progress: 0-100 })
@@ -61,6 +63,7 @@ const mimeType = 'model/x3d+xml'
61
63
  const serialize = (options, ...objects) => {
62
64
  const defaults = {
63
65
  color: [0, 0, 1, 1.0], // default colorRGBA specification
66
+ smooth: false,
64
67
  decimals: 1000,
65
68
  metadata: true,
66
69
  unit: 'millimeter', // millimeter, inch, feet, meter or micrometer
@@ -80,20 +83,20 @@ const serialize = (options, ...objects) => {
80
83
  let body = ['X3D',
81
84
  {
82
85
  profile: 'Interchange',
83
- version: '4.0',
86
+ version: '3.3',
84
87
  'xmlns:xsd': 'http://www.w3.org/2001/XMLSchema-instance',
85
- 'xsd:noNamespaceSchemaLocation': 'http://www.web3d.org/specifications/x3d-4.0.xsd'
88
+ 'xsd:noNamespaceSchemaLocation': 'http://www.web3d.org/specifications/x3d-3.3.xsd'
86
89
  }
87
90
  ]
88
91
  if (options.metadata) {
89
92
  body.push(['head', {},
90
93
  ['meta', { name: 'creator', content: 'Created by JSCAD' }],
91
94
  ['meta', { name: 'reference', content: 'https://www.openjscad.xyz' }],
92
- ['meta', { name: 'created', content: new Date().toISOString()}]
95
+ ['meta', { name: 'created', content: new Date().toISOString() }]
93
96
  ])
94
97
  } else {
95
98
  body.push(['head', {},
96
- ['meta', { name: 'creator', content: 'Created by JSCAD' }],
99
+ ['meta', { name: 'creator', content: 'Created by JSCAD' }]
97
100
  ])
98
101
  }
99
102
  body = body.concat(convertObjects(objects, options))
@@ -108,7 +111,6 @@ ${stringify(body, 2)}`
108
111
  }
109
112
 
110
113
  const convertObjects = (objects, options) => {
111
- let scene = ['Scene', {}]
112
114
  const shapes = []
113
115
  objects.forEach((object, i) => {
114
116
  options.statusCallback && options.statusCallback({ progress: 100 * i / objects.length })
@@ -128,7 +130,8 @@ const convertObjects = (objects, options) => {
128
130
  shapes.push(convertPath2(object, options))
129
131
  }
130
132
  })
131
- scene = scene.concat(shapes)
133
+ const transform = ['Transform', { rotation: '1 0 0 -1.5708' }, ...shapes]
134
+ const scene = ['Scene', {}, transform]
132
135
  return [scene]
133
136
  }
134
137
 
@@ -138,9 +141,9 @@ const convertObjects = (objects, options) => {
138
141
  const convertPath2 = (object, options) => {
139
142
  const points = path2.toPoints(object).slice()
140
143
  if (points.length > 1 && object.isClosed) points.push(points[0])
141
- shape = ['Shape', {}, convertPolyline2D(poly2.create(points), options)]
144
+ const shape = ['Shape', {}, convertPolyline2D(poly2.create(points), options)]
142
145
  if (object.color) {
143
- shape.push(convertAppearance(object, options))
146
+ shape.push(convertAppearance(object, 'emissiveColor', options))
144
147
  }
145
148
  return shape
146
149
  }
@@ -155,7 +158,7 @@ const convertGeom2 = (object, options) => {
155
158
  if (outline.length > 1) outline.push(outline[0]) // close the outline for conversion
156
159
  const shape = ['Shape', {}, convertPolyline2D(poly2.create(outline), options)]
157
160
  if (object.color) {
158
- shape.push(convertAppearance(object, options))
161
+ shape.push(convertAppearance(object, 'emissiveColor', options))
159
162
  }
160
163
  group.push(shape)
161
164
  })
@@ -167,13 +170,17 @@ const convertGeom2 = (object, options) => {
167
170
  */
168
171
  const convertPolyline2D = (object, options) => {
169
172
  const lineSegments = object.vertices.map((p) => `${p[0]} ${p[1]}`).join(' ')
170
- return ['Polyline2D', {lineSegments}]
173
+ return ['Polyline2D', { lineSegments }]
171
174
  }
172
175
 
173
- const convertAppearance = (object, options) => {
174
- const diffuseColor = object.color.join(' ')
175
- const emissiveColor = object.color.join(' ')
176
- return ['Appearance', ['Material', {diffuseColor, emissiveColor}]]
176
+ /*
177
+ * Convert color to Appearance
178
+ */
179
+ const convertAppearance = (object, colorField, options) => {
180
+ const colorRGB = object.color.slice(0, 3)
181
+ const color = colorRGB.join(' ')
182
+ const transparency = roundToDecimals(1.0 - object.color[3], options)
183
+ return ['Appearance', ['Material', { [colorField]: color, transparency }]]
177
184
  }
178
185
 
179
186
  /*
@@ -181,9 +188,11 @@ const convertAppearance = (object, options) => {
181
188
  */
182
189
  const convertGeom3 = (object, options) => {
183
190
  const shape = ['Shape', {}, convertMesh(object, options)]
191
+ let appearance = ['Appearance', {}, ['Material']]
184
192
  if (object.color) {
185
- shape.push(convertAppearance(object, options))
193
+ appearance = convertAppearance(object, 'diffuseColor', options)
186
194
  }
195
+ shape.push(appearance)
187
196
  return shape
188
197
  }
189
198
 
@@ -197,10 +206,10 @@ const convertMesh = (object, options) => {
197
206
 
198
207
  const faceset = [
199
208
  'IndexedTriangleSet',
200
- { ccw: 'true', colorPerVertex: 'false', solid: 'false', index: indexList },
201
- ['Coordinate', { point: pointList }],
209
+ { ccw: 'true', colorPerVertex: 'false', normalPerVertex: options.smooth, solid: 'false', index: indexList },
210
+ ['Coordinate', { point: pointList }]
202
211
  ]
203
- if (! object.color) {
212
+ if (!object.color) {
204
213
  faceset.push(['Color', { color: colorList }])
205
214
  }
206
215
  return faceset
@@ -236,6 +245,8 @@ const convertToColor = (polygon, options) => {
236
245
  return `${color[0]} ${color[1]} ${color[2]}`
237
246
  }
238
247
 
248
+ const roundToDecimals = (float, options) => Math.round(float * options.decimals) / options.decimals
249
+
239
250
  /*
240
251
  * This function converts the given polygons into three lists
241
252
  * - indexList : index of each vertex in the triangle (tuples)
@@ -257,9 +268,9 @@ const polygons2coordinates = (polygons, options) => {
257
268
 
258
269
  // add the vertex to the list of points (and index) if not found
259
270
  if (!vertexTagToCoordIndexMap.has(id)) {
260
- const x = Math.round(vertex[0] * options.decimals) / options.decimals
261
- const y = Math.round(vertex[1] * options.decimals) / options.decimals
262
- const z = Math.round(vertex[2] * options.decimals) / options.decimals
271
+ const x = roundToDecimals(vertex[0], options)
272
+ const y = roundToDecimals(vertex[1], options)
273
+ const z = roundToDecimals(vertex[2], options)
263
274
  pointList.push(`${x} ${y} ${z}`)
264
275
  vertexTagToCoordIndexMap.set(id, pointList.length - 1)
265
276
  }
@@ -58,7 +58,7 @@ test('serialize 2D geometry to X3D Polyline2D', (t) => {
58
58
  // for color
59
59
  t.is(countOf('Appearance', obs), 2)
60
60
  t.is(countOf('Material', obs), 1)
61
- t.is(countOf('diffuseColor', obs), 1)
61
+ t.is(countOf('diffuseColor', obs), 0)
62
62
  t.is(countOf('emissiveColor', obs), 1)
63
63
 
64
64
 
@@ -79,7 +79,7 @@ test('serialize 2D geometry to X3D Polyline2D', (t) => {
79
79
  // for color
80
80
  t.is(countOf('Appearance', obs), 2)
81
81
  t.is(countOf('Material', obs), 1)
82
- t.is(countOf('diffuseColor', obs), 1)
82
+ t.is(countOf('diffuseColor', obs), 0)
83
83
  t.is(countOf('emissiveColor', obs), 1)
84
84
  })
85
85
 
@@ -19,7 +19,7 @@ test('serialize 3D geometry to X3D IndexedTriangleSet', (t) => {
19
19
  t.is(countOf('name', obs), 3)
20
20
  t.is(countOf('content', obs), 3)
21
21
  t.is(countOf('Created by JSCAD', obs), 1)
22
- t.is(countOf('Scene', obs), 1)
22
+ t.is(countOf('Scene', obs), 2)
23
23
 
24
24
  const geom2 = primitives.cube()
25
25
 
@@ -34,12 +34,12 @@ test('serialize 3D geometry to X3D IndexedTriangleSet', (t) => {
34
34
  t.is(countOf('content', obs), 1)
35
35
  t.is(countOf('Created by JSCAD', obs), 1)
36
36
  t.is(countOf('Scene', obs), 2)
37
+ t.is(countOf('Transform', obs), 2)
37
38
  t.is(countOf('Shape', obs), 2)
38
39
  t.is(countOf('IndexedTriangleSet', obs), 2)
39
40
  t.is(countOf('Coordinate', obs), 1)
40
41
  t.is(countOf('Color', obs), 1)
41
42
 
42
-
43
43
  const geom3 = colors.colorize([0.5, 1, 0.5, 1.0], transforms.center({ relativeTo: [5, 5, 5] }, primitives.cube()))
44
44
 
45
45
  results = serializer.serialize({metadata: false}, geom2, geom3)
@@ -57,8 +57,11 @@ test('serialize 3D geometry to X3D IndexedTriangleSet', (t) => {
57
57
  t.is(countOf('IndexedTriangleSet', obs), 4)
58
58
  t.is(countOf('Coordinate', obs), 2)
59
59
  // for color
60
- t.is(countOf('Color', obs), 3)
61
- t.is(countOf('Appearance', obs), 2)
62
-
63
- })
64
-
60
+ t.is(countOf('<Color', obs), 1)
61
+ t.is(countOf('Appearance', obs), 4)
62
+ // for RGB
63
+ t.is(countOf('diffuseColor="0.5 1 0.5"', obs), 1)
64
+ // for facets
65
+ t.is(countOf('normalPerVertex="false"', obs), 2)
66
+
67
+ })
@@ -48,7 +48,7 @@ test('serialize 2D path to X3D Polyline2D', (t) => {
48
48
  // and color on path3
49
49
  t.is(countOf('Appearance', obs), 2)
50
50
  t.is(countOf('Material', obs), 1)
51
- t.is(countOf('diffuseColor', obs), 1)
51
+ t.is(countOf('diffuseColor', obs), 0)
52
52
  t.is(countOf('emissiveColor', obs), 1)
53
53
 
54
54
  })