three-stdlib 2.29.2 → 2.29.3
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/exporters/STLExporter.cjs +105 -86
- package/exporters/STLExporter.cjs.map +1 -1
- package/exporters/STLExporter.d.ts +21 -14
- package/exporters/STLExporter.js +105 -86
- package/exporters/STLExporter.js.map +1 -1
- package/package.json +1 -1
@@ -1,50 +1,60 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __defProp = Object.defineProperty;
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
4
|
+
var __publicField = (obj, key, value) => {
|
5
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
6
|
+
return value;
|
7
|
+
};
|
2
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
3
9
|
const THREE = require("three");
|
10
|
+
const isMesh = (object) => object.isMesh;
|
4
11
|
class STLExporter {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
);
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
constructor() {
|
13
|
+
__publicField(this, "binary", false);
|
14
|
+
__publicField(this, "output", "");
|
15
|
+
__publicField(this, "offset", 80);
|
16
|
+
// skip header
|
17
|
+
__publicField(this, "objects", []);
|
18
|
+
__publicField(this, "triangles", 0);
|
19
|
+
__publicField(this, "vA", new THREE.Vector3());
|
20
|
+
__publicField(this, "vB", new THREE.Vector3());
|
21
|
+
__publicField(this, "vC", new THREE.Vector3());
|
22
|
+
__publicField(this, "cb", new THREE.Vector3());
|
23
|
+
__publicField(this, "ab", new THREE.Vector3());
|
24
|
+
__publicField(this, "normal", new THREE.Vector3());
|
25
|
+
}
|
26
|
+
parse(scene, options) {
|
27
|
+
this.binary = (options == null ? void 0 : options.binary) !== void 0 ? options == null ? void 0 : options.binary : false;
|
28
|
+
scene.traverse((object) => {
|
29
|
+
if (isMesh(object)) {
|
17
30
|
const geometry = object.geometry;
|
31
|
+
if (!geometry.isBufferGeometry) {
|
32
|
+
throw new Error("THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.");
|
33
|
+
}
|
18
34
|
const index = geometry.index;
|
19
|
-
const positionAttribute = geometry.getAttribute("position");
|
20
|
-
|
21
|
-
|
35
|
+
const positionAttribute = geometry.getAttribute("position") || null;
|
36
|
+
if (!positionAttribute)
|
37
|
+
return;
|
38
|
+
this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3;
|
39
|
+
this.objects.push({
|
22
40
|
object3d: object,
|
23
41
|
geometry
|
24
42
|
});
|
25
43
|
}
|
26
44
|
});
|
27
|
-
|
28
|
-
|
29
|
-
if (binary === true) {
|
30
|
-
const bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
|
45
|
+
if (this.binary) {
|
46
|
+
const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4;
|
31
47
|
const arrayBuffer = new ArrayBuffer(bufferLength);
|
32
|
-
output = new DataView(arrayBuffer);
|
33
|
-
output.setUint32(offset, triangles, true);
|
34
|
-
offset += 4;
|
48
|
+
this.output = new DataView(arrayBuffer);
|
49
|
+
this.output.setUint32(this.offset, this.triangles, true);
|
50
|
+
this.offset += 4;
|
35
51
|
} else {
|
36
|
-
output = "";
|
37
|
-
output += "solid exported\n";
|
52
|
+
this.output = "";
|
53
|
+
this.output += "solid exported\n";
|
38
54
|
}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
const cb = new THREE.Vector3();
|
43
|
-
const ab = new THREE.Vector3();
|
44
|
-
const normal = new THREE.Vector3();
|
45
|
-
for (let i = 0, il = objects.length; i < il; i++) {
|
46
|
-
const object = objects[i].object3d;
|
47
|
-
const geometry = objects[i].geometry;
|
55
|
+
for (let i = 0, il = this.objects.length; i < il; i++) {
|
56
|
+
const object = this.objects[i].object3d;
|
57
|
+
const geometry = this.objects[i].geometry;
|
48
58
|
const index = geometry.index;
|
49
59
|
const positionAttribute = geometry.getAttribute("position");
|
50
60
|
if (index !== null) {
|
@@ -52,73 +62,82 @@ class STLExporter {
|
|
52
62
|
const a = index.getX(j + 0);
|
53
63
|
const b = index.getX(j + 1);
|
54
64
|
const c = index.getX(j + 2);
|
55
|
-
writeFace(a, b, c, positionAttribute, object);
|
65
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
56
66
|
}
|
57
67
|
} else {
|
58
68
|
for (let j = 0; j < positionAttribute.count; j += 3) {
|
59
69
|
const a = j + 0;
|
60
70
|
const b = j + 1;
|
61
71
|
const c = j + 2;
|
62
|
-
writeFace(a, b, c, positionAttribute, object);
|
72
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
63
73
|
}
|
64
74
|
}
|
65
75
|
}
|
66
|
-
if (binary
|
67
|
-
output += "endsolid exported\n";
|
76
|
+
if (!this.binary) {
|
77
|
+
this.output += "endsolid exported\n";
|
68
78
|
}
|
69
|
-
return output;
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
vC.applyMatrix4(object.matrixWorld);
|
82
|
-
writeNormal(vA, vB, vC);
|
83
|
-
writeVertex(vA);
|
84
|
-
writeVertex(vB);
|
85
|
-
writeVertex(vC);
|
86
|
-
if (binary === true) {
|
87
|
-
output.setUint16(offset, 0, true);
|
88
|
-
offset += 2;
|
79
|
+
return this.output;
|
80
|
+
}
|
81
|
+
writeFace(a, b, c, positionAttribute, object) {
|
82
|
+
this.vA.fromBufferAttribute(positionAttribute, a);
|
83
|
+
this.vB.fromBufferAttribute(positionAttribute, b);
|
84
|
+
this.vC.fromBufferAttribute(positionAttribute, c);
|
85
|
+
if (object.isSkinnedMesh) {
|
86
|
+
const mesh = object;
|
87
|
+
if ("applyBoneTransform" in mesh) {
|
88
|
+
mesh.applyBoneTransform(a, this.vA);
|
89
|
+
mesh.applyBoneTransform(b, this.vB);
|
90
|
+
mesh.applyBoneTransform(c, this.vC);
|
89
91
|
} else {
|
90
|
-
|
91
|
-
|
92
|
+
mesh.boneTransform(a, this.vA);
|
93
|
+
mesh.boneTransform(b, this.vB);
|
94
|
+
mesh.boneTransform(c, this.vC);
|
92
95
|
}
|
93
96
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
output += " facet normal " + normal.x + " " + normal.y + " " + normal.z + "\n";
|
108
|
-
output += " outer loop\n";
|
109
|
-
}
|
97
|
+
this.vA.applyMatrix4(object.matrixWorld);
|
98
|
+
this.vB.applyMatrix4(object.matrixWorld);
|
99
|
+
this.vC.applyMatrix4(object.matrixWorld);
|
100
|
+
this.writeNormal(this.vA, this.vB, this.vC);
|
101
|
+
this.writeVertex(this.vA);
|
102
|
+
this.writeVertex(this.vB);
|
103
|
+
this.writeVertex(this.vC);
|
104
|
+
if (this.binary && this.output instanceof DataView) {
|
105
|
+
this.output.setUint16(this.offset, 0, true);
|
106
|
+
this.offset += 2;
|
107
|
+
} else {
|
108
|
+
this.output += " endloop\n";
|
109
|
+
this.output += " endfacet\n";
|
110
110
|
}
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
111
|
+
}
|
112
|
+
writeNormal(vA, vB, vC) {
|
113
|
+
this.cb.subVectors(vC, vB);
|
114
|
+
this.ab.subVectors(vA, vB);
|
115
|
+
this.cb.cross(this.ab).normalize();
|
116
|
+
this.normal.copy(this.cb).normalize();
|
117
|
+
if (this.binary && this.output instanceof DataView) {
|
118
|
+
this.output.setFloat32(this.offset, this.normal.x, true);
|
119
|
+
this.offset += 4;
|
120
|
+
this.output.setFloat32(this.offset, this.normal.y, true);
|
121
|
+
this.offset += 4;
|
122
|
+
this.output.setFloat32(this.offset, this.normal.z, true);
|
123
|
+
this.offset += 4;
|
124
|
+
} else {
|
125
|
+
this.output += ` facet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}
|
126
|
+
`;
|
127
|
+
this.output += " outer loop\n";
|
128
|
+
}
|
129
|
+
}
|
130
|
+
writeVertex(vertex) {
|
131
|
+
if (this.binary && this.output instanceof DataView) {
|
132
|
+
this.output.setFloat32(this.offset, vertex.x, true);
|
133
|
+
this.offset += 4;
|
134
|
+
this.output.setFloat32(this.offset, vertex.y, true);
|
135
|
+
this.offset += 4;
|
136
|
+
this.output.setFloat32(this.offset, vertex.z, true);
|
137
|
+
this.offset += 4;
|
138
|
+
} else {
|
139
|
+
this.output += ` vertex ${vertex.x} ${vertex.y} ${vertex.z}
|
140
|
+
`;
|
122
141
|
}
|
123
142
|
}
|
124
143
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"STLExporter.cjs","sources":["../../src/exporters/STLExporter.
|
1
|
+
{"version":3,"file":"STLExporter.cjs","sources":["../../src/exporters/STLExporter.ts"],"sourcesContent":["import {\n BufferAttribute,\n BufferGeometry,\n InterleavedBufferAttribute,\n Mesh,\n Object3D,\n SkinnedMesh,\n Vector3,\n} from 'three'\n\nexport interface STLExporterOptionsBinary {\n binary: true\n}\n\nexport interface STLExporterOptionsString {\n binary?: false\n}\n\nexport interface STLExporterOptions {\n binary?: boolean\n}\n\nconst isMesh = (object: unknown): object is Mesh => (object as any).isMesh\n\nexport class STLExporter {\n private binary = false\n\n private output: string | DataView = ''\n private offset: number = 80 // skip header\n\n private objects: { object3d: Object3D; geometry: BufferGeometry }[] = []\n private triangles: number = 0\n\n private vA = new Vector3()\n private vB = new Vector3()\n private vC = new Vector3()\n private cb = new Vector3()\n private ab = new Vector3()\n private normal = new Vector3()\n\n parse(scene: Object3D, options: STLExporterOptionsBinary): DataView\n parse(scene: Object3D, options?: STLExporterOptionsString): string\n parse(scene: Object3D, options?: STLExporterOptions): string | DataView {\n this.binary = options?.binary !== undefined ? options?.binary : false\n\n scene.traverse((object: Object3D) => {\n if (isMesh(object)) {\n const geometry = object.geometry\n\n if (!geometry.isBufferGeometry) {\n throw new Error('THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.')\n }\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position') || null\n if (!positionAttribute) return\n\n this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3\n\n this.objects.push({\n object3d: object,\n geometry: geometry,\n })\n }\n })\n\n if (this.binary) {\n const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4\n const arrayBuffer = new ArrayBuffer(bufferLength)\n this.output = new DataView(arrayBuffer)\n this.output.setUint32(this.offset, this.triangles, true)\n this.offset += 4\n } else {\n this.output = ''\n this.output += 'solid exported\\n'\n }\n\n for (let i = 0, il = this.objects.length; i < il; i++) {\n const object = this.objects[i].object3d\n const geometry = this.objects[i].geometry\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position')\n\n if (index !== null) {\n // indexed geometry\n for (let j = 0; j < index.count; j += 3) {\n const a = index.getX(j + 0)\n const b = index.getX(j + 1)\n const c = index.getX(j + 2)\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n } else {\n // non-indexed geometry\n for (let j = 0; j < positionAttribute.count; j += 3) {\n const a = j + 0\n const b = j + 1\n const c = j + 2\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n }\n }\n\n if (!this.binary) {\n this.output += 'endsolid exported\\n'\n }\n\n return this.output\n }\n\n private writeFace(\n a: number,\n b: number,\n c: number,\n positionAttribute: BufferAttribute | InterleavedBufferAttribute,\n object: SkinnedMesh,\n ): void {\n this.vA.fromBufferAttribute(positionAttribute, a)\n this.vB.fromBufferAttribute(positionAttribute, b)\n this.vC.fromBufferAttribute(positionAttribute, c)\n\n if (object.isSkinnedMesh) {\n const mesh = object as Omit<SkinnedMesh, 'boneTransform' | 'applyBoneTransform'> &\n (\n | {\n boneTransform(index: number, vector: Vector3): Vector3\n }\n | {\n applyBoneTransform(index: number, vector: Vector3): Vector3\n }\n )\n\n // r151 https://github.com/mrdoob/three.js/pull/25586\n if ('applyBoneTransform' in mesh) {\n mesh.applyBoneTransform(a, this.vA)\n mesh.applyBoneTransform(b, this.vB)\n mesh.applyBoneTransform(c, this.vC)\n } else {\n mesh.boneTransform(a, this.vA)\n mesh.boneTransform(b, this.vB)\n mesh.boneTransform(c, this.vC)\n }\n }\n\n this.vA.applyMatrix4(object.matrixWorld)\n this.vB.applyMatrix4(object.matrixWorld)\n this.vC.applyMatrix4(object.matrixWorld)\n\n this.writeNormal(this.vA, this.vB, this.vC)\n\n this.writeVertex(this.vA)\n this.writeVertex(this.vB)\n this.writeVertex(this.vC)\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setUint16(this.offset, 0, true)\n this.offset += 2\n } else {\n this.output += '\\t\\tendloop\\n'\n this.output += '\\tendfacet\\n'\n }\n }\n\n private writeNormal(vA: Vector3, vB: Vector3, vC: Vector3): void {\n this.cb.subVectors(vC, vB)\n this.ab.subVectors(vA, vB)\n this.cb.cross(this.ab).normalize()\n\n this.normal.copy(this.cb).normalize()\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, this.normal.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.z, true)\n this.offset += 4\n } else {\n this.output += `\\tfacet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}\\n`\n this.output += '\\t\\touter loop\\n'\n }\n }\n\n private writeVertex(vertex: Vector3): void {\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, vertex.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.z, true)\n this.offset += 4\n } else {\n this.output += `\\t\\t\\tvertex ${vertex.x} ${vertex.y} ${vertex.z}\\n`\n }\n }\n}\n"],"names":["Vector3"],"mappings":"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"}
|
@@ -1,21 +1,28 @@
|
|
1
|
-
import { Object3D } from 'three'
|
2
|
-
|
1
|
+
import { Object3D } from 'three';
|
3
2
|
export interface STLExporterOptionsBinary {
|
4
|
-
|
3
|
+
binary: true;
|
5
4
|
}
|
6
|
-
|
7
5
|
export interface STLExporterOptionsString {
|
8
|
-
|
6
|
+
binary?: false;
|
9
7
|
}
|
10
|
-
|
11
8
|
export interface STLExporterOptions {
|
12
|
-
|
9
|
+
binary?: boolean;
|
13
10
|
}
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
export declare class STLExporter {
|
12
|
+
private binary;
|
13
|
+
private output;
|
14
|
+
private offset;
|
15
|
+
private objects;
|
16
|
+
private triangles;
|
17
|
+
private vA;
|
18
|
+
private vB;
|
19
|
+
private vC;
|
20
|
+
private cb;
|
21
|
+
private ab;
|
22
|
+
private normal;
|
23
|
+
parse(scene: Object3D, options: STLExporterOptionsBinary): DataView;
|
24
|
+
parse(scene: Object3D, options?: STLExporterOptionsString): string;
|
25
|
+
private writeFace;
|
26
|
+
private writeNormal;
|
27
|
+
private writeVertex;
|
21
28
|
}
|
package/exporters/STLExporter.js
CHANGED
@@ -1,48 +1,58 @@
|
|
1
|
+
var __defProp = Object.defineProperty;
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
3
|
+
var __publicField = (obj, key, value) => {
|
4
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
5
|
+
return value;
|
6
|
+
};
|
1
7
|
import { Vector3 } from "three";
|
8
|
+
const isMesh = (object) => object.isMesh;
|
2
9
|
class STLExporter {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
);
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
constructor() {
|
11
|
+
__publicField(this, "binary", false);
|
12
|
+
__publicField(this, "output", "");
|
13
|
+
__publicField(this, "offset", 80);
|
14
|
+
// skip header
|
15
|
+
__publicField(this, "objects", []);
|
16
|
+
__publicField(this, "triangles", 0);
|
17
|
+
__publicField(this, "vA", new Vector3());
|
18
|
+
__publicField(this, "vB", new Vector3());
|
19
|
+
__publicField(this, "vC", new Vector3());
|
20
|
+
__publicField(this, "cb", new Vector3());
|
21
|
+
__publicField(this, "ab", new Vector3());
|
22
|
+
__publicField(this, "normal", new Vector3());
|
23
|
+
}
|
24
|
+
parse(scene, options) {
|
25
|
+
this.binary = (options == null ? void 0 : options.binary) !== void 0 ? options == null ? void 0 : options.binary : false;
|
26
|
+
scene.traverse((object) => {
|
27
|
+
if (isMesh(object)) {
|
15
28
|
const geometry = object.geometry;
|
29
|
+
if (!geometry.isBufferGeometry) {
|
30
|
+
throw new Error("THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.");
|
31
|
+
}
|
16
32
|
const index = geometry.index;
|
17
|
-
const positionAttribute = geometry.getAttribute("position");
|
18
|
-
|
19
|
-
|
33
|
+
const positionAttribute = geometry.getAttribute("position") || null;
|
34
|
+
if (!positionAttribute)
|
35
|
+
return;
|
36
|
+
this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3;
|
37
|
+
this.objects.push({
|
20
38
|
object3d: object,
|
21
39
|
geometry
|
22
40
|
});
|
23
41
|
}
|
24
42
|
});
|
25
|
-
|
26
|
-
|
27
|
-
if (binary === true) {
|
28
|
-
const bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
|
43
|
+
if (this.binary) {
|
44
|
+
const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4;
|
29
45
|
const arrayBuffer = new ArrayBuffer(bufferLength);
|
30
|
-
output = new DataView(arrayBuffer);
|
31
|
-
output.setUint32(offset, triangles, true);
|
32
|
-
offset += 4;
|
46
|
+
this.output = new DataView(arrayBuffer);
|
47
|
+
this.output.setUint32(this.offset, this.triangles, true);
|
48
|
+
this.offset += 4;
|
33
49
|
} else {
|
34
|
-
output = "";
|
35
|
-
output += "solid exported\n";
|
50
|
+
this.output = "";
|
51
|
+
this.output += "solid exported\n";
|
36
52
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
const cb = new Vector3();
|
41
|
-
const ab = new Vector3();
|
42
|
-
const normal = new Vector3();
|
43
|
-
for (let i = 0, il = objects.length; i < il; i++) {
|
44
|
-
const object = objects[i].object3d;
|
45
|
-
const geometry = objects[i].geometry;
|
53
|
+
for (let i = 0, il = this.objects.length; i < il; i++) {
|
54
|
+
const object = this.objects[i].object3d;
|
55
|
+
const geometry = this.objects[i].geometry;
|
46
56
|
const index = geometry.index;
|
47
57
|
const positionAttribute = geometry.getAttribute("position");
|
48
58
|
if (index !== null) {
|
@@ -50,73 +60,82 @@ class STLExporter {
|
|
50
60
|
const a = index.getX(j + 0);
|
51
61
|
const b = index.getX(j + 1);
|
52
62
|
const c = index.getX(j + 2);
|
53
|
-
writeFace(a, b, c, positionAttribute, object);
|
63
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
54
64
|
}
|
55
65
|
} else {
|
56
66
|
for (let j = 0; j < positionAttribute.count; j += 3) {
|
57
67
|
const a = j + 0;
|
58
68
|
const b = j + 1;
|
59
69
|
const c = j + 2;
|
60
|
-
writeFace(a, b, c, positionAttribute, object);
|
70
|
+
this.writeFace(a, b, c, positionAttribute, object);
|
61
71
|
}
|
62
72
|
}
|
63
73
|
}
|
64
|
-
if (binary
|
65
|
-
output += "endsolid exported\n";
|
74
|
+
if (!this.binary) {
|
75
|
+
this.output += "endsolid exported\n";
|
66
76
|
}
|
67
|
-
return output;
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
vC.applyMatrix4(object.matrixWorld);
|
80
|
-
writeNormal(vA, vB, vC);
|
81
|
-
writeVertex(vA);
|
82
|
-
writeVertex(vB);
|
83
|
-
writeVertex(vC);
|
84
|
-
if (binary === true) {
|
85
|
-
output.setUint16(offset, 0, true);
|
86
|
-
offset += 2;
|
77
|
+
return this.output;
|
78
|
+
}
|
79
|
+
writeFace(a, b, c, positionAttribute, object) {
|
80
|
+
this.vA.fromBufferAttribute(positionAttribute, a);
|
81
|
+
this.vB.fromBufferAttribute(positionAttribute, b);
|
82
|
+
this.vC.fromBufferAttribute(positionAttribute, c);
|
83
|
+
if (object.isSkinnedMesh) {
|
84
|
+
const mesh = object;
|
85
|
+
if ("applyBoneTransform" in mesh) {
|
86
|
+
mesh.applyBoneTransform(a, this.vA);
|
87
|
+
mesh.applyBoneTransform(b, this.vB);
|
88
|
+
mesh.applyBoneTransform(c, this.vC);
|
87
89
|
} else {
|
88
|
-
|
89
|
-
|
90
|
+
mesh.boneTransform(a, this.vA);
|
91
|
+
mesh.boneTransform(b, this.vB);
|
92
|
+
mesh.boneTransform(c, this.vC);
|
90
93
|
}
|
91
94
|
}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
output += " facet normal " + normal.x + " " + normal.y + " " + normal.z + "\n";
|
106
|
-
output += " outer loop\n";
|
107
|
-
}
|
95
|
+
this.vA.applyMatrix4(object.matrixWorld);
|
96
|
+
this.vB.applyMatrix4(object.matrixWorld);
|
97
|
+
this.vC.applyMatrix4(object.matrixWorld);
|
98
|
+
this.writeNormal(this.vA, this.vB, this.vC);
|
99
|
+
this.writeVertex(this.vA);
|
100
|
+
this.writeVertex(this.vB);
|
101
|
+
this.writeVertex(this.vC);
|
102
|
+
if (this.binary && this.output instanceof DataView) {
|
103
|
+
this.output.setUint16(this.offset, 0, true);
|
104
|
+
this.offset += 2;
|
105
|
+
} else {
|
106
|
+
this.output += " endloop\n";
|
107
|
+
this.output += " endfacet\n";
|
108
108
|
}
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
109
|
+
}
|
110
|
+
writeNormal(vA, vB, vC) {
|
111
|
+
this.cb.subVectors(vC, vB);
|
112
|
+
this.ab.subVectors(vA, vB);
|
113
|
+
this.cb.cross(this.ab).normalize();
|
114
|
+
this.normal.copy(this.cb).normalize();
|
115
|
+
if (this.binary && this.output instanceof DataView) {
|
116
|
+
this.output.setFloat32(this.offset, this.normal.x, true);
|
117
|
+
this.offset += 4;
|
118
|
+
this.output.setFloat32(this.offset, this.normal.y, true);
|
119
|
+
this.offset += 4;
|
120
|
+
this.output.setFloat32(this.offset, this.normal.z, true);
|
121
|
+
this.offset += 4;
|
122
|
+
} else {
|
123
|
+
this.output += ` facet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}
|
124
|
+
`;
|
125
|
+
this.output += " outer loop\n";
|
126
|
+
}
|
127
|
+
}
|
128
|
+
writeVertex(vertex) {
|
129
|
+
if (this.binary && this.output instanceof DataView) {
|
130
|
+
this.output.setFloat32(this.offset, vertex.x, true);
|
131
|
+
this.offset += 4;
|
132
|
+
this.output.setFloat32(this.offset, vertex.y, true);
|
133
|
+
this.offset += 4;
|
134
|
+
this.output.setFloat32(this.offset, vertex.z, true);
|
135
|
+
this.offset += 4;
|
136
|
+
} else {
|
137
|
+
this.output += ` vertex ${vertex.x} ${vertex.y} ${vertex.z}
|
138
|
+
`;
|
120
139
|
}
|
121
140
|
}
|
122
141
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"STLExporter.js","sources":["../../src/exporters/STLExporter.
|
1
|
+
{"version":3,"file":"STLExporter.js","sources":["../../src/exporters/STLExporter.ts"],"sourcesContent":["import {\n BufferAttribute,\n BufferGeometry,\n InterleavedBufferAttribute,\n Mesh,\n Object3D,\n SkinnedMesh,\n Vector3,\n} from 'three'\n\nexport interface STLExporterOptionsBinary {\n binary: true\n}\n\nexport interface STLExporterOptionsString {\n binary?: false\n}\n\nexport interface STLExporterOptions {\n binary?: boolean\n}\n\nconst isMesh = (object: unknown): object is Mesh => (object as any).isMesh\n\nexport class STLExporter {\n private binary = false\n\n private output: string | DataView = ''\n private offset: number = 80 // skip header\n\n private objects: { object3d: Object3D; geometry: BufferGeometry }[] = []\n private triangles: number = 0\n\n private vA = new Vector3()\n private vB = new Vector3()\n private vC = new Vector3()\n private cb = new Vector3()\n private ab = new Vector3()\n private normal = new Vector3()\n\n parse(scene: Object3D, options: STLExporterOptionsBinary): DataView\n parse(scene: Object3D, options?: STLExporterOptionsString): string\n parse(scene: Object3D, options?: STLExporterOptions): string | DataView {\n this.binary = options?.binary !== undefined ? options?.binary : false\n\n scene.traverse((object: Object3D) => {\n if (isMesh(object)) {\n const geometry = object.geometry\n\n if (!geometry.isBufferGeometry) {\n throw new Error('THREE.STLExporter: Geometry is not of type THREE.BufferGeometry.')\n }\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position') || null\n if (!positionAttribute) return\n\n this.triangles += index !== null ? index.count / 3 : positionAttribute.count / 3\n\n this.objects.push({\n object3d: object,\n geometry: geometry,\n })\n }\n })\n\n if (this.binary) {\n const bufferLength = this.triangles * 2 + this.triangles * 3 * 4 * 4 + 80 + 4\n const arrayBuffer = new ArrayBuffer(bufferLength)\n this.output = new DataView(arrayBuffer)\n this.output.setUint32(this.offset, this.triangles, true)\n this.offset += 4\n } else {\n this.output = ''\n this.output += 'solid exported\\n'\n }\n\n for (let i = 0, il = this.objects.length; i < il; i++) {\n const object = this.objects[i].object3d\n const geometry = this.objects[i].geometry\n\n const index = geometry.index\n const positionAttribute = geometry.getAttribute('position')\n\n if (index !== null) {\n // indexed geometry\n for (let j = 0; j < index.count; j += 3) {\n const a = index.getX(j + 0)\n const b = index.getX(j + 1)\n const c = index.getX(j + 2)\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n } else {\n // non-indexed geometry\n for (let j = 0; j < positionAttribute.count; j += 3) {\n const a = j + 0\n const b = j + 1\n const c = j + 2\n\n this.writeFace(a, b, c, positionAttribute, object as SkinnedMesh)\n }\n }\n }\n\n if (!this.binary) {\n this.output += 'endsolid exported\\n'\n }\n\n return this.output\n }\n\n private writeFace(\n a: number,\n b: number,\n c: number,\n positionAttribute: BufferAttribute | InterleavedBufferAttribute,\n object: SkinnedMesh,\n ): void {\n this.vA.fromBufferAttribute(positionAttribute, a)\n this.vB.fromBufferAttribute(positionAttribute, b)\n this.vC.fromBufferAttribute(positionAttribute, c)\n\n if (object.isSkinnedMesh) {\n const mesh = object as Omit<SkinnedMesh, 'boneTransform' | 'applyBoneTransform'> &\n (\n | {\n boneTransform(index: number, vector: Vector3): Vector3\n }\n | {\n applyBoneTransform(index: number, vector: Vector3): Vector3\n }\n )\n\n // r151 https://github.com/mrdoob/three.js/pull/25586\n if ('applyBoneTransform' in mesh) {\n mesh.applyBoneTransform(a, this.vA)\n mesh.applyBoneTransform(b, this.vB)\n mesh.applyBoneTransform(c, this.vC)\n } else {\n mesh.boneTransform(a, this.vA)\n mesh.boneTransform(b, this.vB)\n mesh.boneTransform(c, this.vC)\n }\n }\n\n this.vA.applyMatrix4(object.matrixWorld)\n this.vB.applyMatrix4(object.matrixWorld)\n this.vC.applyMatrix4(object.matrixWorld)\n\n this.writeNormal(this.vA, this.vB, this.vC)\n\n this.writeVertex(this.vA)\n this.writeVertex(this.vB)\n this.writeVertex(this.vC)\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setUint16(this.offset, 0, true)\n this.offset += 2\n } else {\n this.output += '\\t\\tendloop\\n'\n this.output += '\\tendfacet\\n'\n }\n }\n\n private writeNormal(vA: Vector3, vB: Vector3, vC: Vector3): void {\n this.cb.subVectors(vC, vB)\n this.ab.subVectors(vA, vB)\n this.cb.cross(this.ab).normalize()\n\n this.normal.copy(this.cb).normalize()\n\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, this.normal.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, this.normal.z, true)\n this.offset += 4\n } else {\n this.output += `\\tfacet normal ${this.normal.x} ${this.normal.y} ${this.normal.z}\\n`\n this.output += '\\t\\touter loop\\n'\n }\n }\n\n private writeVertex(vertex: Vector3): void {\n if (this.binary && this.output instanceof DataView) {\n this.output.setFloat32(this.offset, vertex.x, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.y, true)\n this.offset += 4\n this.output.setFloat32(this.offset, vertex.z, true)\n this.offset += 4\n } else {\n this.output += `\\t\\t\\tvertex ${vertex.x} ${vertex.y} ${vertex.z}\\n`\n }\n }\n}\n"],"names":[],"mappings":"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"}
|