@jscad/x3d-serializer 2.3.9 → 2.4.2
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 +27 -0
- package/README.md +6 -2
- package/package.json +4 -4
- package/{index.js → src/index.js} +102 -31
- package/tests/geom2ToX3D.test.js +85 -0
- package/tests/geom3ToX3D.test.js +64 -0
- package/tests/path2ToX3D.test.js +55 -0
- package/tests/serialize.test.js +0 -69
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,33 @@
|
|
|
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.2](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/x3d-serializer@2.4.1...@jscad/x3d-serializer@2.4.2) (2022-08-21)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @jscad/x3d-serializer
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [2.4.1](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/x3d-serializer@2.4.0...@jscad/x3d-serializer@2.4.1) (2022-07-17)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @jscad/x3d-serializer
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# [2.4.0](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/x3d-serializer@2.3.9...@jscad/x3d-serializer@2.4.0) (2022-06-12)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* **x3d-serializer:** enhanced to convert 2D geometry and path to X3D Polyline2D ([#1091](https://github.com/jscad/OpenJSCAD.org/issues/1091)) ([4f763a8](https://github.com/jscad/OpenJSCAD.org/commit/4f763a8def39f3b0454f2079f3c1fd7da52dd880))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
6
33
|
## [2.3.9](https://github.com/jscad/OpenJSCAD.org/compare/@jscad/x3d-serializer@2.3.8...@jscad/x3d-serializer@2.3.9) (2022-05-15)
|
|
7
34
|
|
|
8
35
|
**Note:** Version bump only for package @jscad/x3d-serializer
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://github.com/jscad/OpenJSCAD.org/blob/master/LICENSE)
|
|
10
10
|
|
|
11
11
|
[](https://openjscad.nodebb.com/)
|
|
12
|
-
[](https://
|
|
12
|
+
[](https://lerna.js.org/)
|
|
13
13
|
[](https://standardjs.com)
|
|
14
14
|
|
|
15
15
|
[](https://opencollective.com/openjscad)
|
|
@@ -23,7 +23,11 @@ This serializer outputs a 'blobable' array of data from one or more JSCAD geomet
|
|
|
23
23
|
The array of data can either be used to create a Blob (`new Blob(blobable)`), or converted to a Node.js buffer.
|
|
24
24
|
|
|
25
25
|
The serialization of the following geometries are possible.
|
|
26
|
-
- serialization of 3D
|
|
26
|
+
- serialization of 3D geometries (geom3) to X3D IndexedTriangleSet (a unique mesh containing coordinates)
|
|
27
|
+
- serialization of 2D geometries (geom2) to X3D Polyline2D
|
|
28
|
+
- serialization of 2D paths (path2) to X3D Polyline2D
|
|
29
|
+
|
|
30
|
+
Material (color) is added to X3D shapes when found on the geometry.
|
|
27
31
|
|
|
28
32
|
## Table of Contents
|
|
29
33
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jscad/x3d-serializer",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "X3D Serializer for JSCAD",
|
|
5
5
|
"homepage": "https://openjscad.xyz/",
|
|
6
6
|
"repository": "https://github.com/jscad/OpenJSCAD.org",
|
|
7
|
-
"main": "index.js",
|
|
7
|
+
"main": "src/index.js",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"coverage": "nyc --all --reporter=html --reporter=text npm test",
|
|
10
10
|
"test": "ava --verbose --timeout 2m './tests/*.test.js'"
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@jscad/array-utils": "2.1.4",
|
|
36
|
-
"@jscad/modeling": "2.
|
|
36
|
+
"@jscad/modeling": "2.10.0",
|
|
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": "
|
|
43
|
+
"gitHead": "13572067545460affd53b64b3ab834a39af8c7e5"
|
|
44
44
|
}
|
|
@@ -3,30 +3,36 @@ JSCAD Object to X3D (XML) Format Serialization
|
|
|
3
3
|
|
|
4
4
|
## License
|
|
5
5
|
|
|
6
|
-
Copyright (c) 2018 JSCAD Organization https://github.com/jscad
|
|
6
|
+
Copyright (c) 2018-2022 JSCAD Organization https://github.com/jscad
|
|
7
7
|
|
|
8
8
|
All code released under MIT license
|
|
9
9
|
|
|
10
10
|
Notes:
|
|
11
11
|
1) geom2 conversion to:
|
|
12
|
-
|
|
12
|
+
Polyline2D with lineSegment and Color
|
|
13
13
|
2) geom3 conversion to:
|
|
14
14
|
IndexedTriangleSet with Coordinates and Colors
|
|
15
15
|
3) path2 conversion to:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
TBD
|
|
19
|
-
1) gzipped is also possible; same mime type, with file extension .x3dz
|
|
16
|
+
Polyline2D with lineSegment and Color
|
|
20
17
|
*/
|
|
21
18
|
|
|
22
19
|
/**
|
|
23
|
-
* Serializer of JSCAD geometries to X3D
|
|
20
|
+
* Serializer of JSCAD geometries to X3D source data (XML).
|
|
21
|
+
*
|
|
22
|
+
* The serialization of the following geometries are possible.
|
|
23
|
+
* - serialization of 3D geometries (geom3) to X3D IndexedTriangleSet (a unique mesh containing coordinates)
|
|
24
|
+
* - serialization of 2D geometries (geom2) to X3D Polyline2D
|
|
25
|
+
* - serialization of 2D paths (path2) to X3D Polyline2D
|
|
26
|
+
*
|
|
27
|
+
* Material (color) is added to X3D shapes when found on the geometry.
|
|
28
|
+
*
|
|
24
29
|
* @module io/x3d-serializer
|
|
25
30
|
* @example
|
|
26
31
|
* const { serializer, mimeType } = require('@jscad/x3d-serializer')
|
|
27
32
|
*/
|
|
28
33
|
|
|
29
34
|
const { geometries, modifiers } = require('@jscad/modeling')
|
|
35
|
+
const { geom2, geom3, path2, poly2, poly3 } = geometries
|
|
30
36
|
|
|
31
37
|
const { flatten, toArray } = require('@jscad/array-utils')
|
|
32
38
|
|
|
@@ -41,6 +47,8 @@ const mimeType = 'model/x3d+xml'
|
|
|
41
47
|
/**
|
|
42
48
|
* Serialize the give objects to X3D elements (XML).
|
|
43
49
|
* @param {Object} options - options for serialization, REQUIRED
|
|
50
|
+
* @param {Array} [options.color=[0,0,1,1]] - default color for objects
|
|
51
|
+
* @param {Boolean} [options.metadata=true] - add metadata to 3MF contents, such at CreationDate
|
|
44
52
|
* @param {String} [options.unit='millimeter'] - unit of design; millimeter, inch, feet, meter or micrometer
|
|
45
53
|
* @param {Function} [options.statusCallback] - call back function for progress ({ progress: 0-100 })
|
|
46
54
|
* @param {Object|Array} objects - objects to serialize as X3D
|
|
@@ -52,23 +60,19 @@ const mimeType = 'model/x3d+xml'
|
|
|
52
60
|
*/
|
|
53
61
|
const serialize = (options, ...objects) => {
|
|
54
62
|
const defaults = {
|
|
55
|
-
unit: 'millimeter', // millimeter, inch, feet, meter or micrometer
|
|
56
63
|
color: [0, 0, 1, 1.0], // default colorRGBA specification
|
|
57
64
|
decimals: 1000,
|
|
65
|
+
metadata: true,
|
|
66
|
+
unit: 'millimeter', // millimeter, inch, feet, meter or micrometer
|
|
58
67
|
statusCallback: null
|
|
59
68
|
}
|
|
60
69
|
options = Object.assign({}, defaults, options)
|
|
61
70
|
|
|
62
71
|
objects = flatten(objects)
|
|
63
72
|
|
|
64
|
-
|
|
65
|
-
let objects3d = objects.filter((object) => geometries.geom3.isA(object))
|
|
66
|
-
|
|
67
|
-
if (objects3d.length === 0) throw new Error('only 3D geometries can be serialized to X3D')
|
|
68
|
-
if (objects.length !== objects3d.length) console.warn('some objects could not be serialized to X3D')
|
|
73
|
+
objects = objects.filter((object) => geom3.isA(object) || geom2.isA(object) || path2.isA(object))
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
objects3d = toArray(modifiers.generalize({ snap: true, triangulate: true }, objects3d))
|
|
75
|
+
if (objects.length === 0) throw new Error('expected one or more geom3/geom2/path2 objects')
|
|
72
76
|
|
|
73
77
|
options.statusCallback && options.statusCallback({ progress: 0 })
|
|
74
78
|
|
|
@@ -76,15 +80,23 @@ const serialize = (options, ...objects) => {
|
|
|
76
80
|
let body = ['X3D',
|
|
77
81
|
{
|
|
78
82
|
profile: 'Interchange',
|
|
79
|
-
version: '
|
|
83
|
+
version: '4.0',
|
|
80
84
|
'xmlns:xsd': 'http://www.w3.org/2001/XMLSchema-instance',
|
|
81
|
-
'xsd:noNamespaceSchemaLocation': 'http://www.web3d.org/specifications/x3d-
|
|
82
|
-
}
|
|
83
|
-
['head', {},
|
|
84
|
-
['meta', { name: 'creator', content: 'Created by JSCAD' }]
|
|
85
|
-
]
|
|
85
|
+
'xsd:noNamespaceSchemaLocation': 'http://www.web3d.org/specifications/x3d-4.0.xsd'
|
|
86
|
+
}
|
|
86
87
|
]
|
|
87
|
-
|
|
88
|
+
if (options.metadata) {
|
|
89
|
+
body.push(['head', {},
|
|
90
|
+
['meta', { name: 'creator', content: 'Created by JSCAD' }],
|
|
91
|
+
['meta', { name: 'reference', content: 'https://www.openjscad.xyz' }],
|
|
92
|
+
['meta', { name: 'created', content: new Date().toISOString()}]
|
|
93
|
+
])
|
|
94
|
+
} else {
|
|
95
|
+
body.push(['head', {},
|
|
96
|
+
['meta', { name: 'creator', content: 'Created by JSCAD' }],
|
|
97
|
+
])
|
|
98
|
+
}
|
|
99
|
+
body = body.concat(convertObjects(objects, options))
|
|
88
100
|
|
|
89
101
|
// convert the contents to X3D (XML) format
|
|
90
102
|
const contents = `<?xml version="1.0" encoding="UTF-8"?>
|
|
@@ -101,20 +113,77 @@ const convertObjects = (objects, options) => {
|
|
|
101
113
|
objects.forEach((object, i) => {
|
|
102
114
|
options.statusCallback && options.statusCallback({ progress: 100 * i / objects.length })
|
|
103
115
|
|
|
104
|
-
if (
|
|
105
|
-
|
|
116
|
+
if (geom3.isA(object)) {
|
|
117
|
+
// convert to triangles
|
|
118
|
+
object = modifiers.generalize({ snap: true, triangulate: true }, object)
|
|
119
|
+
const polygons = geom3.toPolygons(object)
|
|
106
120
|
if (polygons.length > 0) {
|
|
107
|
-
|
|
108
|
-
shapes.push(convertShape(object, options))
|
|
121
|
+
shapes.push(convertGeom3(object, options))
|
|
109
122
|
}
|
|
110
123
|
}
|
|
124
|
+
if (geom2.isA(object)) {
|
|
125
|
+
shapes.push(convertGeom2(object, options))
|
|
126
|
+
}
|
|
127
|
+
if (path2.isA(object)) {
|
|
128
|
+
shapes.push(convertPath2(object, options))
|
|
129
|
+
}
|
|
111
130
|
})
|
|
112
131
|
scene = scene.concat(shapes)
|
|
113
132
|
return [scene]
|
|
114
133
|
}
|
|
115
134
|
|
|
116
|
-
|
|
135
|
+
/*
|
|
136
|
+
* Convert the given object (path2) to X3D source
|
|
137
|
+
*/
|
|
138
|
+
const convertPath2 = (object, options) => {
|
|
139
|
+
const points = path2.toPoints(object).slice()
|
|
140
|
+
if (points.length > 1 && object.isClosed) points.push(points[0])
|
|
141
|
+
shape = ['Shape', {}, convertPolyline2D(poly2.create(points), options)]
|
|
142
|
+
if (object.color) {
|
|
143
|
+
shape.push(convertAppearance(object, options))
|
|
144
|
+
}
|
|
145
|
+
return shape
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/*
|
|
149
|
+
* Convert the given object (geom2) to X3D source
|
|
150
|
+
*/
|
|
151
|
+
const convertGeom2 = (object, options) => {
|
|
152
|
+
const outlines = geom2.toOutlines(object)
|
|
153
|
+
const group = ['Group', {}]
|
|
154
|
+
outlines.forEach((outline) => {
|
|
155
|
+
if (outline.length > 1) outline.push(outline[0]) // close the outline for conversion
|
|
156
|
+
const shape = ['Shape', {}, convertPolyline2D(poly2.create(outline), options)]
|
|
157
|
+
if (object.color) {
|
|
158
|
+
shape.push(convertAppearance(object, options))
|
|
159
|
+
}
|
|
160
|
+
group.push(shape)
|
|
161
|
+
})
|
|
162
|
+
return group
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
* Convert the given object (poly2) to X3D source
|
|
167
|
+
*/
|
|
168
|
+
const convertPolyline2D = (object, options) => {
|
|
169
|
+
const lineSegments = object.vertices.map((p) => `${p[0]} ${p[1]}`).join(' ')
|
|
170
|
+
return ['Polyline2D', {lineSegments}]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const convertAppearance = (object, options) => {
|
|
174
|
+
const diffuseColor = object.color.join(' ')
|
|
175
|
+
const emissiveColor = object.color.join(' ')
|
|
176
|
+
return ['Appearance', ['Material', {diffuseColor, emissiveColor}]]
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
* Convert the given object (geom3) to X3D source
|
|
181
|
+
*/
|
|
182
|
+
const convertGeom3 = (object, options) => {
|
|
117
183
|
const shape = ['Shape', {}, convertMesh(object, options)]
|
|
184
|
+
if (object.color) {
|
|
185
|
+
shape.push(convertAppearance(object, options))
|
|
186
|
+
}
|
|
118
187
|
return shape
|
|
119
188
|
}
|
|
120
189
|
|
|
@@ -130,18 +199,20 @@ const convertMesh = (object, options) => {
|
|
|
130
199
|
'IndexedTriangleSet',
|
|
131
200
|
{ ccw: 'true', colorPerVertex: 'false', solid: 'false', index: indexList },
|
|
132
201
|
['Coordinate', { point: pointList }],
|
|
133
|
-
['Color', { color: colorList }]
|
|
134
202
|
]
|
|
203
|
+
if (! object.color) {
|
|
204
|
+
faceset.push(['Color', { color: colorList }])
|
|
205
|
+
}
|
|
135
206
|
return faceset
|
|
136
207
|
}
|
|
137
208
|
|
|
138
209
|
const convertToTriangles = (object, options) => {
|
|
139
210
|
const triangles = []
|
|
140
|
-
const polygons =
|
|
211
|
+
const polygons = geom3.toPolygons(object)
|
|
141
212
|
polygons.forEach((poly) => {
|
|
142
213
|
const firstVertex = poly.vertices[0]
|
|
143
214
|
for (let i = poly.vertices.length - 3; i >= 0; i--) {
|
|
144
|
-
const triangle =
|
|
215
|
+
const triangle = poly3.fromPoints([
|
|
145
216
|
firstVertex,
|
|
146
217
|
poly.vertices[i + 1],
|
|
147
218
|
poly.vertices[i + 2]
|
|
@@ -165,7 +236,7 @@ const convertToColor = (polygon, options) => {
|
|
|
165
236
|
return `${color[0]} ${color[1]} ${color[2]}`
|
|
166
237
|
}
|
|
167
238
|
|
|
168
|
-
|
|
239
|
+
/*
|
|
169
240
|
* This function converts the given polygons into three lists
|
|
170
241
|
* - indexList : index of each vertex in the triangle (tuples)
|
|
171
242
|
* - pointList : coordinates of each vertex (X Y Z)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const test = require('ava')
|
|
2
|
+
|
|
3
|
+
const countOf = require('../../test/helpers/countOf')
|
|
4
|
+
|
|
5
|
+
const { colors, geometries, primitives } = require('@jscad/modeling')
|
|
6
|
+
|
|
7
|
+
const { serialize } = require('../src/index.js')
|
|
8
|
+
|
|
9
|
+
test('serialize 2D geometry to X3D Polyline2D', (t) => {
|
|
10
|
+
const shape1 = geometries.geom2.create()
|
|
11
|
+
|
|
12
|
+
let results = serialize({}, shape1)
|
|
13
|
+
t.is(results.length, 1)
|
|
14
|
+
|
|
15
|
+
let obs = results[0]
|
|
16
|
+
t.is(countOf('X3D', obs), 2)
|
|
17
|
+
t.is(countOf('head', obs), 2)
|
|
18
|
+
t.is(countOf('meta', obs), 3)
|
|
19
|
+
t.is(countOf('name', obs), 3)
|
|
20
|
+
t.is(countOf('content', obs), 3)
|
|
21
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
22
|
+
t.is(countOf('Scene', obs), 2)
|
|
23
|
+
t.is(countOf('Group', obs), 1)
|
|
24
|
+
|
|
25
|
+
const shape2 = primitives.rectangle()
|
|
26
|
+
|
|
27
|
+
results = serialize({metadata: false}, shape2)
|
|
28
|
+
t.is(results.length, 1)
|
|
29
|
+
|
|
30
|
+
obs = results[0]
|
|
31
|
+
t.is(countOf('X3D', obs), 2)
|
|
32
|
+
t.is(countOf('head', obs), 2)
|
|
33
|
+
t.is(countOf('meta', obs), 1)
|
|
34
|
+
t.is(countOf('name', obs), 1)
|
|
35
|
+
t.is(countOf('content', obs), 1)
|
|
36
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
37
|
+
t.is(countOf('Scene', obs), 2)
|
|
38
|
+
t.is(countOf('Group', obs), 2)
|
|
39
|
+
t.is(countOf('Shape', obs), 2)
|
|
40
|
+
t.is(countOf('Polyline2D', obs), 1)
|
|
41
|
+
|
|
42
|
+
const shape3 = colors.colorize([0, 0, 0], shape2)
|
|
43
|
+
|
|
44
|
+
results = serialize({metadata: false}, shape3)
|
|
45
|
+
t.is(results.length, 1)
|
|
46
|
+
|
|
47
|
+
obs = results[0]
|
|
48
|
+
t.is(countOf('X3D', obs), 2)
|
|
49
|
+
t.is(countOf('head', obs), 2)
|
|
50
|
+
t.is(countOf('meta', obs), 1)
|
|
51
|
+
t.is(countOf('name', obs), 1)
|
|
52
|
+
t.is(countOf('content', obs), 1)
|
|
53
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
54
|
+
t.is(countOf('Scene', obs), 2)
|
|
55
|
+
t.is(countOf('Group', obs), 2)
|
|
56
|
+
t.is(countOf('Shape', obs), 2)
|
|
57
|
+
t.is(countOf('Polyline2D', obs), 1)
|
|
58
|
+
// for color
|
|
59
|
+
t.is(countOf('Appearance', obs), 2)
|
|
60
|
+
t.is(countOf('Material', obs), 1)
|
|
61
|
+
t.is(countOf('diffuseColor', obs), 1)
|
|
62
|
+
t.is(countOf('emissiveColor', obs), 1)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
results = serialize({metadata: false}, shape2, shape3)
|
|
66
|
+
t.is(results.length, 1)
|
|
67
|
+
|
|
68
|
+
obs = results[0]
|
|
69
|
+
t.is(countOf('X3D', obs), 2)
|
|
70
|
+
t.is(countOf('head', obs), 2)
|
|
71
|
+
t.is(countOf('meta', obs), 1)
|
|
72
|
+
t.is(countOf('name', obs), 1)
|
|
73
|
+
t.is(countOf('content', obs), 1)
|
|
74
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
75
|
+
t.is(countOf('Scene', obs), 2)
|
|
76
|
+
t.is(countOf('Group', obs), 4)
|
|
77
|
+
t.is(countOf('Shape', obs), 4)
|
|
78
|
+
t.is(countOf('Polyline2D', obs), 2)
|
|
79
|
+
// for color
|
|
80
|
+
t.is(countOf('Appearance', obs), 2)
|
|
81
|
+
t.is(countOf('Material', obs), 1)
|
|
82
|
+
t.is(countOf('diffuseColor', obs), 1)
|
|
83
|
+
t.is(countOf('emissiveColor', obs), 1)
|
|
84
|
+
})
|
|
85
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const test = require('ava')
|
|
2
|
+
|
|
3
|
+
const countOf = require('../../test/helpers/countOf')
|
|
4
|
+
|
|
5
|
+
const { colors, geometries, primitives, transforms } = require('@jscad/modeling')
|
|
6
|
+
|
|
7
|
+
const serializer = require('../src/index.js')
|
|
8
|
+
|
|
9
|
+
test('serialize 3D geometry to X3D IndexedTriangleSet', (t) => {
|
|
10
|
+
const geom1 = geometries.geom3.create()
|
|
11
|
+
|
|
12
|
+
let results = serializer.serialize({}, geom1)
|
|
13
|
+
t.is(results.length, 1)
|
|
14
|
+
|
|
15
|
+
let obs = results[0]
|
|
16
|
+
t.is(countOf('X3D', obs), 2)
|
|
17
|
+
t.is(countOf('head', obs), 2)
|
|
18
|
+
t.is(countOf('meta', obs), 3)
|
|
19
|
+
t.is(countOf('name', obs), 3)
|
|
20
|
+
t.is(countOf('content', obs), 3)
|
|
21
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
22
|
+
t.is(countOf('Scene', obs), 1)
|
|
23
|
+
|
|
24
|
+
const geom2 = primitives.cube()
|
|
25
|
+
|
|
26
|
+
results = serializer.serialize({metadata: false}, geom2)
|
|
27
|
+
t.is(results.length, 1)
|
|
28
|
+
|
|
29
|
+
obs = results[0]
|
|
30
|
+
t.is(countOf('X3D', obs), 2)
|
|
31
|
+
t.is(countOf('head', obs), 2)
|
|
32
|
+
t.is(countOf('meta', obs), 1)
|
|
33
|
+
t.is(countOf('name', obs), 1)
|
|
34
|
+
t.is(countOf('content', obs), 1)
|
|
35
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
36
|
+
t.is(countOf('Scene', obs), 2)
|
|
37
|
+
t.is(countOf('Shape', obs), 2)
|
|
38
|
+
t.is(countOf('IndexedTriangleSet', obs), 2)
|
|
39
|
+
t.is(countOf('Coordinate', obs), 1)
|
|
40
|
+
t.is(countOf('Color', obs), 1)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
const geom3 = colors.colorize([0.5, 1, 0.5, 1.0], transforms.center({ relativeTo: [5, 5, 5] }, primitives.cube()))
|
|
44
|
+
|
|
45
|
+
results = serializer.serialize({metadata: false}, geom2, geom3)
|
|
46
|
+
t.is(results.length, 1)
|
|
47
|
+
|
|
48
|
+
obs = results[0]
|
|
49
|
+
t.is(countOf('X3D', obs), 2)
|
|
50
|
+
t.is(countOf('head', obs), 2)
|
|
51
|
+
t.is(countOf('meta', obs), 1)
|
|
52
|
+
t.is(countOf('name', obs), 1)
|
|
53
|
+
t.is(countOf('content', obs), 1)
|
|
54
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
55
|
+
t.is(countOf('Scene', obs), 2)
|
|
56
|
+
t.is(countOf('Shape', obs), 4)
|
|
57
|
+
t.is(countOf('IndexedTriangleSet', obs), 4)
|
|
58
|
+
t.is(countOf('Coordinate', obs), 2)
|
|
59
|
+
// for color
|
|
60
|
+
t.is(countOf('Color', obs), 3)
|
|
61
|
+
t.is(countOf('Appearance', obs), 2)
|
|
62
|
+
|
|
63
|
+
})
|
|
64
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const test = require('ava')
|
|
2
|
+
|
|
3
|
+
const countOf = require('../../test/helpers/countOf')
|
|
4
|
+
|
|
5
|
+
const { colors, geometries, primitives } = require('@jscad/modeling')
|
|
6
|
+
|
|
7
|
+
const { serialize } = require('../src/index.js')
|
|
8
|
+
|
|
9
|
+
test('serialize 2D path to X3D Polyline2D', (t) => {
|
|
10
|
+
const path1 = geometries.path2.create()
|
|
11
|
+
|
|
12
|
+
let results = serialize({}, path1)
|
|
13
|
+
t.is(results.length, 1)
|
|
14
|
+
|
|
15
|
+
let obs = results[0]
|
|
16
|
+
t.is(countOf('X3D', obs), 2)
|
|
17
|
+
t.is(countOf('head', obs), 2)
|
|
18
|
+
t.is(countOf('meta', obs), 3)
|
|
19
|
+
t.is(countOf('name', obs), 3)
|
|
20
|
+
t.is(countOf('content', obs), 3)
|
|
21
|
+
t.is(countOf('Created by JSCAD', obs), 1)
|
|
22
|
+
|
|
23
|
+
const path2 = primitives.arc({ center: [5, 5], endAngle: 45, segments: 16 })
|
|
24
|
+
|
|
25
|
+
results = serialize({metadata: false}, path2)
|
|
26
|
+
t.is(results.length, 1)
|
|
27
|
+
|
|
28
|
+
obs = results[0]
|
|
29
|
+
t.is(countOf('X3D', obs), 2)
|
|
30
|
+
t.is(countOf('head', obs), 2)
|
|
31
|
+
t.is(countOf('Scene', obs), 2)
|
|
32
|
+
t.is(countOf('Shape', obs), 2)
|
|
33
|
+
t.is(countOf('Polyline2D', obs), 1)
|
|
34
|
+
t.is(countOf('lineSegments', obs), 1)
|
|
35
|
+
|
|
36
|
+
const path3 = colors.colorize([0, 0, 0], path2)
|
|
37
|
+
|
|
38
|
+
results = serialize({metadata: false}, path2, path3)
|
|
39
|
+
t.is(results.length, 1)
|
|
40
|
+
|
|
41
|
+
obs = results[0]
|
|
42
|
+
t.is(countOf('X3D', obs), 2)
|
|
43
|
+
t.is(countOf('head', obs), 2)
|
|
44
|
+
t.is(countOf('Scene', obs), 2)
|
|
45
|
+
t.is(countOf('Shape', obs), 4)
|
|
46
|
+
t.is(countOf('Polyline2D', obs), 2)
|
|
47
|
+
t.is(countOf('lineSegments', obs), 2)
|
|
48
|
+
// and color on path3
|
|
49
|
+
t.is(countOf('Appearance', obs), 2)
|
|
50
|
+
t.is(countOf('Material', obs), 1)
|
|
51
|
+
t.is(countOf('diffuseColor', obs), 1)
|
|
52
|
+
t.is(countOf('emissiveColor', obs), 1)
|
|
53
|
+
|
|
54
|
+
})
|
|
55
|
+
|
package/tests/serialize.test.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
const test = require('ava')
|
|
2
|
-
|
|
3
|
-
const { colors, geometries, primitives, transforms } = require('@jscad/modeling')
|
|
4
|
-
|
|
5
|
-
const serializer = require('../index.js')
|
|
6
|
-
|
|
7
|
-
test('serialize 3D geometry to X3D', (t) => {
|
|
8
|
-
const geom1 = geometries.geom3.create()
|
|
9
|
-
|
|
10
|
-
const observed1 = serializer.serialize({}, geom1)
|
|
11
|
-
t.deepEqual(observed1, [expected1])
|
|
12
|
-
|
|
13
|
-
const geom2 = primitives.cube()
|
|
14
|
-
|
|
15
|
-
const observed2 = serializer.serialize({}, geom2)
|
|
16
|
-
t.deepEqual(observed2, [expected2])
|
|
17
|
-
|
|
18
|
-
const geom3 = colors.colorize([0.5, 1, 0.5, 1.0], transforms.center({ relativeTo: [5, 5, 5] }, primitives.cube()))
|
|
19
|
-
|
|
20
|
-
const observed3 = serializer.serialize({}, geom2, geom3)
|
|
21
|
-
t.deepEqual(observed3, [expected3])
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
const expected1 = `<?xml version="1.0" encoding="UTF-8"?>
|
|
25
|
-
<X3D profile="Interchange" version="3.3" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="http://www.web3d.org/specifications/x3d-3.3.xsd">
|
|
26
|
-
<head>
|
|
27
|
-
<meta name="creator" content="Created by JSCAD"/>
|
|
28
|
-
</head>
|
|
29
|
-
<Scene/>
|
|
30
|
-
</X3D>
|
|
31
|
-
`
|
|
32
|
-
|
|
33
|
-
const expected2 = `<?xml version="1.0" encoding="UTF-8"?>
|
|
34
|
-
<X3D profile="Interchange" version="3.3" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="http://www.web3d.org/specifications/x3d-3.3.xsd">
|
|
35
|
-
<head>
|
|
36
|
-
<meta name="creator" content="Created by JSCAD"/>
|
|
37
|
-
</head>
|
|
38
|
-
<Scene>
|
|
39
|
-
<Shape>
|
|
40
|
-
<IndexedTriangleSet ccw="true" colorPerVertex="false" solid="false" index="0 1 2 0 2 3 4 5 6 4 6 7 0 4 7 0 7 1 3 2 6 3 6 5 0 3 5 0 5 4 1 7 6 1 6 2">
|
|
41
|
-
<Coordinate point="-1 -1 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 -1 1 1 -1 1 1 1 1 -1 1"/>
|
|
42
|
-
<Color color="0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1"/>
|
|
43
|
-
</IndexedTriangleSet>
|
|
44
|
-
</Shape>
|
|
45
|
-
</Scene>
|
|
46
|
-
</X3D>
|
|
47
|
-
`
|
|
48
|
-
|
|
49
|
-
const expected3 = `<?xml version="1.0" encoding="UTF-8"?>
|
|
50
|
-
<X3D profile="Interchange" version="3.3" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="http://www.web3d.org/specifications/x3d-3.3.xsd">
|
|
51
|
-
<head>
|
|
52
|
-
<meta name="creator" content="Created by JSCAD"/>
|
|
53
|
-
</head>
|
|
54
|
-
<Scene>
|
|
55
|
-
<Shape>
|
|
56
|
-
<IndexedTriangleSet ccw="true" colorPerVertex="false" solid="false" index="0 1 2 0 2 3 4 5 6 4 6 7 0 4 7 0 7 1 3 2 6 3 6 5 0 3 5 0 5 4 1 7 6 1 6 2">
|
|
57
|
-
<Coordinate point="-1 -1 -1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 -1 1 1 -1 1 1 1 1 -1 1"/>
|
|
58
|
-
<Color color="0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1"/>
|
|
59
|
-
</IndexedTriangleSet>
|
|
60
|
-
</Shape>
|
|
61
|
-
<Shape>
|
|
62
|
-
<IndexedTriangleSet ccw="true" colorPerVertex="false" solid="false" index="0 1 2 0 2 3 4 5 6 4 6 7 0 4 7 0 7 1 3 2 6 3 6 5 0 3 5 0 5 4 1 7 6 1 6 2">
|
|
63
|
-
<Coordinate point="4 4 4 4 4 6 4 6 6 4 6 4 6 4 4 6 6 4 6 6 6 6 4 6"/>
|
|
64
|
-
<Color color="0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5 0.5 1 0.5"/>
|
|
65
|
-
</IndexedTriangleSet>
|
|
66
|
-
</Shape>
|
|
67
|
-
</Scene>
|
|
68
|
-
</X3D>
|
|
69
|
-
`
|