xl-public-utils 1.0.4 → 1.0.6

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/index.js CHANGED
@@ -2,4 +2,5 @@ import * as vtkUtils from './src/vtkUtils.mjs';
2
2
  import * as utils from './src/utils.mjs'
3
3
  import * as qrcode from './src/qrcode.mjs'
4
4
  import * as BwipJs from './src/bwip-js.mjs';
5
- export { vtkUtils, utils, qrcode, BwipJs };
5
+ import * as drcUtils from './src/drcUtils.mjs';
6
+ export { vtkUtils, utils, qrcode, BwipJs, drcUtils };
package/package.json CHANGED
@@ -1,16 +1,21 @@
1
1
  {
2
2
  "name": "xl-public-utils",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
+ "type": "module",
5
6
  "main": "index.js",
6
7
  "module": "index.js",
7
8
  "types": "index.d.ts",
8
9
  "peerDependencies": {
9
- "@kitware/vtk.js": ">=25.7.2"
10
+ "@kitware/vtk.js": ">=25.7.2",
11
+ "gl-matrix": ">=3.4.3"
10
12
  },
11
13
  "peerDependenciesMeta": {
12
14
  "@kitware/vtk.js": {
13
15
  "optional": true
16
+ },
17
+ "gl-matrix": {
18
+ "optional": true
14
19
  }
15
20
  },
16
21
  "exports": {
@@ -21,11 +26,14 @@
21
26
  "./bwipJs": "./src/bwip-js.mjs"
22
27
  },
23
28
  "scripts": {
24
- "test": "echo \"Error: no test specified\" && exit 1"
29
+ "test": "jest"
25
30
  },
26
31
  "keywords": [
27
32
  "一些通用方法"
28
33
  ],
29
34
  "author": "xl",
30
- "license": "ISC"
35
+ "license": "ISC",
36
+ "devDependencies": {
37
+ "typescript": "^5.6.3"
38
+ }
31
39
  }
@@ -0,0 +1,353 @@
1
+ import { vec3 } from "gl-matrix";
2
+ import { int8ArrayToBase64 } from './utils.mjs'
3
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
4
+ /**
5
+ * @typedef {Object} AttrOption
6
+ * @property {number[]} [colors] 颜色数组
7
+ * @property {number[]} [generics] 属性数组
8
+ * @property {number[]} [normals] 法向量数组
9
+ */
10
+
11
+ /**
12
+ * 将数据进行压缩
13
+ * @param {number[]} vertices 网格点
14
+ * @param {number[]} faces 网格面,必须是三角化之后的面,每连续的三个点索引标识一个面
15
+ * @param {number} byteLength=14 byteLength 压缩率
16
+ * @param {AttrOption} [attr] 其他需要压缩的属性
17
+ * @returns {Int8Array} 压缩之后的DRC数据
18
+ */
19
+ export function enCodeMeshByVF(vertices, faces, byteLength = 14, attr =undefined) {
20
+ const facesFlat = faces;
21
+ const pointFlat = vertices;
22
+ const encoderModule = window.encoderModule
23
+ const encoder = new encoderModule.Encoder();
24
+ const meshBuilder = new encoderModule.MeshBuilder();
25
+ const dracoMesh = new encoderModule.Mesh();
26
+ const numberFaces = faces.length / 3;
27
+ const numberPoints = vertices.length / 3;
28
+ meshBuilder.AddFacesToMesh(dracoMesh, numberFaces, facesFlat);
29
+ meshBuilder.AddFloatAttributeToMesh(dracoMesh, encoderModule.POSITION, numberPoints, 3, pointFlat);
30
+ if (attr) {
31
+ if (attr.colors && attr.colors.length) {
32
+ meshBuilder.AddFloatAttributeToMesh(dracoMesh, encoderModule.COLOR, numberPoints, 3, attr.colors);
33
+ }
34
+ if (attr.normals && attr.normals.length) {
35
+ meshBuilder.AddFloatAttributeToMesh(dracoMesh, encoderModule.NORMAL, numberPoints, 3, attr.normals);
36
+ }
37
+ if (attr.generics && attr.generics.length) {
38
+ meshBuilder.AddFloatAttributeToMesh(dracoMesh, encoderModule.GENERIC, numberPoints, 3, attr.generics);
39
+ }
40
+ }
41
+
42
+ // encoder.SetSpeedOptions(5, 5);
43
+ encoder.SetAttributeQuantization(encoderModule.POSITION, byteLength);
44
+ encoder.SetEncodingMethod(encoderModule.MESH_EDGEBREAKER_ENCODING);
45
+ const encodedData = new encoderModule.DracoInt8Array();
46
+ const encodedLen = encoder.EncodeMeshToDracoBuffer(dracoMesh, encodedData);
47
+ const outputBuffer = new ArrayBuffer(encodedLen);
48
+ const outputData = new Int8Array(outputBuffer);
49
+ for (let i = 0; i < encodedLen; ++i) {
50
+ outputData[i] = encodedData.GetValue(i);
51
+ }
52
+ encoderModule.destroy(dracoMesh);
53
+ encoderModule.destroy(encoder);
54
+ encoderModule.destroy(meshBuilder);
55
+ return outputData
56
+ }
57
+
58
+ /**
59
+ * 使用drc压缩点
60
+ * @param {vec3[] | number[]} points 点数组
61
+ * @returns {Int8Array} 压缩之后的drc data
62
+ */
63
+ export function enCodePointCloud(points) {
64
+ const encoderModule = window.encoderModule
65
+ const encoder = new encoderModule.Encoder();
66
+ const pointCloudBuilder = new encoderModule.PointCloudBuilder();
67
+ const dracoPointCloud = new encoderModule.PointCloud();
68
+ const pointsFlat = [];
69
+ for(let i= 0; i <points.length; i++) {
70
+ if(typeof points[i] === 'object') {
71
+ pointsFlat.push(points[i][0], points[i][1], points[i][2]);
72
+ } else {
73
+ pointsFlat.push(points[i])
74
+ }
75
+ }
76
+ const numberPoints = pointsFlat.length / 3;
77
+ pointCloudBuilder.AddFloatAttribute(dracoPointCloud, encoderModule.POSITION, numberPoints, 3, pointsFlat);
78
+
79
+ encoder.SetAttributeQuantization(encoderModule.POSITION, 14);
80
+
81
+ encoder.SetEncodingMethod(encoderModule.MESH_SEQUENTIAL_ENCODING);
82
+ const encodedData = new encoderModule.DracoInt8Array();
83
+ const encodedLen = encoder.EncodePointCloudToDracoBuffer(dracoPointCloud, false, encodedData);
84
+ const outputBuffer = new ArrayBuffer(encodedLen);
85
+ const outputData = new Int8Array(outputBuffer);
86
+ for (let i = 0; i < encodedLen; ++i) {
87
+ outputData[i] = encodedData.GetValue(i);
88
+ }
89
+ encoderModule.destroy(dracoPointCloud);
90
+ encoderModule.destroy(encoder);
91
+ encoderModule.destroy(pointCloudBuilder);
92
+ return outputData
93
+ }
94
+ /**
95
+ * 解压drc格式的点云数据
96
+ * @param {ArrayBuffer} byteArray drc点数据
97
+ * @returns {Float32Array} 点数组
98
+ */
99
+ export function decodePointCloud(byteArray) {
100
+ const dracoPointCloud = decodeBuffer(byteArray);
101
+ return getPointCloudFromDracoGeometry(dracoPointCloud);
102
+ }
103
+
104
+ /**
105
+ * @typedef {Object} DrcMeshData
106
+ * @property {Uint32Array} faces 网格面数组
107
+ * @property {Float32Array} vertices 网格点数组
108
+ * @property {Float32Array} [colors] 颜色数组
109
+ * @property {Float32Array} [generics] 属性数组
110
+ * @property {Float32Array} [normals] 法向量数组
111
+ */
112
+
113
+ /**
114
+ * 解压drc格式的网格数据
115
+ * @param {ArrayBuffer} byteArray drc网格数据
116
+ * @returns {DrcMeshData} 网格数据
117
+ */
118
+ export function decodeDrcBufferArray(byteArray) {
119
+ var dracoGeometry = decodeBuffer(byteArray);
120
+ return getPolyDataFromDracoGeometry(dracoGeometry);
121
+ }
122
+ /**
123
+ * @typedef {Object} Decoder
124
+ */
125
+
126
+ /**
127
+ * 输入一个Drc数据,反会对应的解压器
128
+ * @param {ArrayBuffer} arrayBuffer 输入的数据
129
+ * @returns {Decoder} drc解压类
130
+ */
131
+ export function decodeBuffer(arrayBuffer) {
132
+ const decoderModule = window.decoderModule;
133
+ var byteArray = new Int8Array(arrayBuffer);
134
+ var decoder = new decoderModule.Decoder();
135
+ var decoderBuffer = new decoderModule.DecoderBuffer();
136
+ decoderBuffer.Init(byteArray, byteArray.length);
137
+ var geometryType = decoder.GetEncodedGeometryType(decoderBuffer);
138
+ var dracoGeometry;
139
+
140
+ if (geometryType === decoderModule.TRIANGULAR_MESH) {
141
+ dracoGeometry = new decoderModule.Mesh();
142
+ var status = decoder.DecodeBufferToMesh(decoderBuffer, dracoGeometry);
143
+
144
+ if (!status.ok()) {
145
+ console.error("Could not decode Draco file: ".concat(status.error_msg()));
146
+ }
147
+ } else if ( geometryType === decoderModule.POINT_CLOUD ) {
148
+ dracoGeometry = new decoderModule.PointCloud();
149
+ var status =
150
+ decoder.DecodeBufferToPointCloud(decoderBuffer, dracoGeometry);
151
+ if(!status.ok()) {
152
+ console.error('Wrong geometry type, expected mesh, got point cloud.');
153
+ }
154
+ }
155
+
156
+ decoderModule.destroy(decoderBuffer);
157
+ decoderModule.destroy(decoder);
158
+ return dracoGeometry;
159
+ }
160
+
161
+ /**
162
+ * 获取drcDecoder中的网格信息
163
+ * @param {Decoder} dracoGeometry DRC网格的decoder
164
+ * @returns {DrcMeshData} decoder中的网格信息
165
+ */
166
+ function getPolyDataFromDracoGeometry(dracoGeometry) {
167
+ const decoderModule = window.decoderModule;
168
+ var decoder = new decoderModule.Decoder(); // Get position attribute ID
169
+
170
+ var positionAttributeId = decoder.GetAttributeId(dracoGeometry, decoderModule.POSITION);
171
+
172
+ if (positionAttributeId === -1) {
173
+ console.error('No position attribute found in the decoded model.');
174
+ decoderModule.destroy(decoder);
175
+ decoderModule.destroy(dracoGeometry);
176
+ return null;
177
+ }
178
+ var positionArray = getDracoAttributeAsFloat32Array(dracoGeometry, positionAttributeId); // Read indices
179
+ var i = dracoGeometry.num_faces();
180
+ var indices = new Uint32Array(i * 4);
181
+ var indicesArray = new decoderModule.DracoInt32Array();
182
+ while (i--) {
183
+ decoder.GetFaceFromMesh(dracoGeometry, i, indicesArray);
184
+ var index = i * 4;
185
+ indices[index] = 3;
186
+ indices[index + 1] = indicesArray.GetValue(0);
187
+ indices[index + 2] = indicesArray.GetValue(1);
188
+ indices[index + 3] = indicesArray.GetValue(2);
189
+ } // Create polyData and add positions and indinces
190
+ var normalAttributeId = decoder.GetAttributeId(dracoGeometry, decoderModule.NORMAL);
191
+ var normals;
192
+ if (normalAttributeId !== -1) {
193
+ normals = getDracoAttributeAsFloat32Array(dracoGeometry, decoderModule.NORMAL);
194
+ } // Texture coordinates
195
+ var genericattributeId = decoder.GetAttributeId(dracoGeometry, decoderModule.GENERIC);
196
+ let generics;
197
+ if (genericattributeId !== -1) {
198
+ generics = getDracoAttributeAsFloat32Array(dracoGeometry, genericattributeId);
199
+ }
200
+
201
+ // var texCoordAttributeId = decoder.GetAttributeId(dracoGeometry, decoderModule.TEX_COORD);
202
+
203
+ // if (texCoordAttributeId !== -1) {
204
+ // var texCoordArray = getDracoAttributeAsFloat32Array(dracoGeometry, texCoordAttributeId);
205
+ // var texCoords = vtkDataArray.newInstance({
206
+ // numberOfComponents: 2,
207
+ // values: texCoordArray,
208
+ // name: 'TCoords'
209
+ // });
210
+ // } // Scalars
211
+
212
+
213
+ var colorAttributeId = decoder.GetAttributeId(dracoGeometry, decoderModule.COLOR);
214
+ let colors;
215
+ if (colorAttributeId !== -1) {
216
+ colors = getDracoAttributeAsFloat32Array(dracoGeometry, colorAttributeId);
217
+ }
218
+
219
+ decoderModule.destroy(decoder);
220
+ return {
221
+ faces: indices,
222
+ vertices: positionArray,
223
+ normals,
224
+ colors,
225
+ generics
226
+ };
227
+ }
228
+
229
+ /**
230
+ * 解压DRC点云数据
231
+ * @param {Decoder} dracoGeometry DRC点云的Decder
232
+ * @returns {Float32Array} 点
233
+ */
234
+ function getPointCloudFromDracoGeometry(dracoGeometry) {
235
+ const decoderModule = window.decoderModule;
236
+ var decoder = new decoderModule.Decoder(); // Get position attribute ID
237
+
238
+ var positionAttributeId = decoder.GetAttributeId(dracoGeometry, decoderModule.POSITION);
239
+
240
+ if (positionAttributeId === -1) {
241
+ console.error('No position attribute found in the decoded model.');
242
+ decoderModule.destroy(decoder);
243
+ decoderModule.destroy(dracoGeometry);
244
+ return new Float32Array();
245
+ } else {
246
+ const points = getDracoAttributeAsFloat32Array(dracoGeometry, positionAttributeId); // Read indices
247
+ decoderModule.destroy(decoder);
248
+ return points;
249
+ }
250
+ }
251
+ /**
252
+ * 获取decoder中的属性
253
+ * @param {Decoder} dracoGeometry DRC Decoder
254
+ * @param {number} attributeId 需要获取的属性id
255
+ * @returns {Float32Array} 对应decoder中的属性
256
+ */
257
+ export function getDracoAttributeAsFloat32Array(dracoGeometry, attributeId) {
258
+ const decoderModule = window.decoderModule;
259
+ var decoder = new decoderModule.Decoder();
260
+ var attribute = decoder.GetAttribute(dracoGeometry, attributeId);
261
+ var numberOfComponents = attribute.num_components();
262
+ var numberOfPoints = dracoGeometry.num_points();
263
+ var attributeData = new decoderModule.DracoFloat32Array();
264
+ decoder.GetAttributeFloatForAllPoints(dracoGeometry, attribute, attributeData);
265
+ var i = numberOfPoints * numberOfComponents;
266
+ var attributeArray = new Float32Array(i);
267
+ while (i--) {
268
+ attributeArray[i] = attributeData.GetValue(i);
269
+ }
270
+
271
+ return attributeArray;
272
+ }
273
+
274
+
275
+ /**
276
+ * 将点数据使用drc压缩处理为 base64 string
277
+ * @param {vec3[] | number[]} points 点数据
278
+ * @returns {string} drc压缩之后的base64数据
279
+ */
280
+
281
+ export function enCloudPointTobase64(points) {
282
+ return int8ArrayToBase64(enCodePointCloud(points));
283
+ }
284
+
285
+
286
+ /**
287
+ * @typedef {Object} Mesh
288
+ * @property {number[][]} vertices 点信息
289
+ * @property {number[][]} faces 面信息
290
+ */
291
+
292
+ /**
293
+ * 使用drc压缩网格信息
294
+ * @param {Mesh | vtkPolyData} mesh
295
+ * @param {number} byteLength=14 压缩率
296
+ * @param {AttrOption} [attr] 其他需要压缩的属性
297
+ * @returns {Int8Array} 压缩之后的DRC数据
298
+ */
299
+
300
+ export function enCodeMesh(mesh, byteLength = 14, attr = undefined) {
301
+ let faces = [];
302
+ let vertices = [];
303
+ if(mesh.vertices && mesh.faces) {
304
+ vertices = mesh.vertices;
305
+ for(let i = 0; i < mesh.faces.length; i++) {
306
+ const face = mesh.faces[i];
307
+ faces.push(face[0]);
308
+ faces.push(face[1]);
309
+ faces.push(face[2]);
310
+ }
311
+ } else if(mesh.getClassName && mesh.getClassName() === 'vtkPolyData') {
312
+ vertices = mesh.getPoints().getData();
313
+ const _vtkFaces = mesh.getPolys().getData();
314
+ const nbFaces = _vtkFaces.length / 4;
315
+ for(let i = 0; i < nbFaces; i++) {
316
+ faces.push(_vtkFaces[i * 4 + 1]);
317
+ faces.push(_vtkFaces[i * 4 + 2]);
318
+ faces.push(_vtkFaces[i * 4 + 3]);
319
+ }
320
+ }
321
+ return enCodeMeshByVF(vertices, faces, byteLength, attr)
322
+ }
323
+
324
+ /**
325
+ * 初始化Draco文件
326
+ */
327
+ export function initDrcCoder() {
328
+ if (!window.encoderModule) {
329
+ const timerEncoder = setInterval(() => {
330
+ if (window.DracoEncoderModule) {
331
+ window.DracoEncoderModule().then((res) => {
332
+ window.encoderModule = res;
333
+ });
334
+ clearInterval(timerEncoder);
335
+ }
336
+ }, 50);
337
+ }
338
+ if (!window.decoderModule) {
339
+ const timerDecoder = setInterval(() => {
340
+ if (window.DracoDecoderModule) {
341
+ window.DracoDecoderModule().then((res) => {
342
+ window.decoderModule = res;
343
+ function a() {
344
+ return res;
345
+ }
346
+ // show.value = true;
347
+ vtkDracoReader.setDracoDecoder(a);
348
+ });
349
+ clearInterval(timerDecoder);
350
+ }
351
+ }, 50);
352
+ }
353
+ }
@@ -0,0 +1,285 @@
1
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
2
+ import { mat4 } from "gl-matrix";
3
+ var FormatTypes = {
4
+ ASCII: 'ascii',
5
+ BINARY: 'binary'
6
+ };
7
+ var TextureCoordinatesName = {
8
+ UV: ['u', 'v'],
9
+ TEXTURE_UV: ['texture_u', 'texture_v']
10
+ };
11
+
12
+ var DEFAULT_VALUES = {
13
+ format: FormatTypes.ASCII,
14
+ dataByteOrder: 0,
15
+ headerComments: [],
16
+ textureFileName: '',
17
+ textureCoordinatesName: TextureCoordinatesName.UV,
18
+ withNormals: false,
19
+ withUVs: false,
20
+ withColors: false,
21
+ withIndices: true
22
+ }
23
+
24
+ var _writeHeader = function writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, vertexCount, faceListLength, withNormals, withUVs, withColors, withIndices) {
25
+ var isBinary = fileFormat !== FormatTypes.ASCII;
26
+ var format;
27
+
28
+ if (isBinary) {
29
+ format = fileType ? 'binary_little_endian' : 'binary_big_endian';
30
+ } else format = 'ascii';
31
+
32
+ headerComments.unshift('VTK.js generated PLY File');
33
+
34
+ if (textureFileName) {
35
+ headerComments.push("TextureFile ".concat(textureFileName));
36
+ }
37
+
38
+ var commentElements = headerComments.map(function (comment) {
39
+ return "comment ".concat(comment);
40
+ }).join('\n');
41
+ var header = ['ply', "format ".concat(format, " 1.0"), "".concat(commentElements), "element vertex ".concat(vertexCount), 'property float x', 'property float y', 'property float z']; // normals
42
+
43
+ if (withNormals) {
44
+ header.push('property float nx', 'property float ny', 'property float nz');
45
+ } // uvs
46
+
47
+
48
+ if (withUVs) {
49
+ header.push("property float ".concat(textureCoordinatesName[0]), "property float ".concat(textureCoordinatesName[1]));
50
+ } // colors
51
+
52
+
53
+ if (withColors) {
54
+ header.push('property uchar red', 'property uchar green', 'property uchar blue');
55
+ } // faces
56
+
57
+
58
+ if (withIndices) {
59
+ header.push("element face ".concat(faceListLength), 'property list uchar int vertex_indices');
60
+ }
61
+
62
+ header.push('end_header\n');
63
+ return header.join('\n');
64
+ };
65
+
66
+ var binaryWriter = function binaryWriter() {
67
+ var output;
68
+ var vOffset;
69
+ var fOffset;
70
+ var indexByteCount = 4;
71
+ var ft;
72
+ return {
73
+ init: function init(polyData) {},
74
+ writeHeader: function writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices) {
75
+ var vertexCount = polyData.getPoints().getNumberOfPoints();
76
+ ft = fileType; // 1 byte shape descriptor
77
+ // 3 vertex indices at ${indexByteCount} bytes
78
+
79
+ var faceListLength = withIndices ? numPolys * (indexByteCount * 3 + 1) : 0; // 3 position values at 4 bytes
80
+ // 3 normal values at 4 bytes
81
+ // 3 color channels with 1 byte
82
+ // 2 uv values at 4 bytes
83
+
84
+ var vertexListLength = vertexCount * (4 * 3 + (withNormals ? 4 * 3 : 0) + (withUVs ? 4 * 2 : 0) + (withColors ? 3 : 0));
85
+
86
+ var header = _writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices);
87
+
88
+ var headerBin = new TextEncoder().encode(header);
89
+ output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
90
+ new Uint8Array(output.buffer).set(headerBin, 0);
91
+ vOffset = headerBin.length;
92
+ fOffset = vOffset + vertexListLength;
93
+ },
94
+ writeVertice: function writeVertice(x, y, z, nx, ny, nz, u, v, r, g, b) {
95
+ // xyz
96
+ output.setFloat32(vOffset, x, ft);
97
+ vOffset += 4;
98
+ output.setFloat32(vOffset, y, ft);
99
+ vOffset += 4;
100
+ output.setFloat32(vOffset, z, ft);
101
+ vOffset += 4; // nxnynz
102
+
103
+ if (nx !== null && ny !== null && nz !== null) {
104
+ output.setFloat32(vOffset, nx, ft);
105
+ vOffset += 4;
106
+ output.setFloat32(vOffset, ny, ft);
107
+ vOffset += 4;
108
+ output.setFloat32(vOffset, nz, ft);
109
+ vOffset += 4;
110
+ } // uv
111
+
112
+
113
+ if (u !== null && v !== null) {
114
+ output.setFloat32(vOffset, u, ft);
115
+ vOffset += 4;
116
+ output.setFloat32(vOffset, v, ft);
117
+ vOffset += 4;
118
+ } // rgb
119
+
120
+
121
+ if (r !== null && g !== null && b !== null) {
122
+ output.setUint8(vOffset, r);
123
+ vOffset += 1;
124
+ output.setUint8(vOffset, g);
125
+ vOffset += 1;
126
+ output.setUint8(vOffset, b);
127
+ vOffset += 1;
128
+ }
129
+ },
130
+ writeFace: function writeFace(n, x, y, z) {
131
+ output.setUint8(fOffset, n);
132
+ fOffset += 1;
133
+ output.setUint32(fOffset, x, ft);
134
+ fOffset += indexByteCount;
135
+ output.setUint32(fOffset, y, ft);
136
+ fOffset += indexByteCount;
137
+ output.setUint32(fOffset, z, ft);
138
+ fOffset += indexByteCount;
139
+ },
140
+ writeFooter: function writeFooter(polyData) {},
141
+ getOutputData: function getOutputData() {
142
+ return output;
143
+ }
144
+ };
145
+ };
146
+
147
+ var asciiWriter = function asciiWriter() {
148
+ var fileContent = '';
149
+ return {
150
+ init: function init(polyData) {},
151
+ writeHeader: function writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices) {
152
+ fileContent += _writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices);
153
+ },
154
+ writeVertice: function writeVertice(x, y, z, nx, ny, nz, u, v, r, g, b) {
155
+ fileContent += "".concat(x, " ").concat(y, " ").concat(z);
156
+
157
+ if (nx !== null && ny !== null && nz !== null) {
158
+ fileContent += " ".concat(nx, " ").concat(ny, " ").concat(nz);
159
+ }
160
+
161
+ if (u !== null && v !== null) {
162
+ fileContent += " ".concat(u, " ").concat(v);
163
+ }
164
+
165
+ if (r !== null && g !== null && b !== null) {
166
+ fileContent += " ".concat(r, " ").concat(g, " ").concat(b);
167
+ }
168
+
169
+ fileContent += '\n';
170
+ },
171
+ writeFace: function writeFace(n, x, y, z) {
172
+ fileContent += "".concat(n, " ").concat(x, " ").concat(y, " ").concat(z, "\n");
173
+ },
174
+ writeFooter: function writeFooter(polyData) {},
175
+ getOutputData: function getOutputData() {
176
+ return fileContent;
177
+ }
178
+ };
179
+ };
180
+
181
+ /**
182
+ * 将polyData转换为ply文件
183
+ * @param {vtkPolyData} polyData 需要导出的polydata
184
+ * @param {'ascii' | 'binary'} format 导出文件格式
185
+ * @param {0 | 1} dataByteOrder=0 字节序,默认为0, 0为大端模式, 1小端模式
186
+ * @param {string[]} headerComments=[] 文件头描述
187
+ * @param {string} textureFileName='' header描述文件名
188
+ * @param {['u', 'v']} textureCoordinatesName=['u', 'v'] header添加u和v
189
+ * @param {boolean} withNormals=false 是否需要法向量
190
+ * @param {boolean} withUVs=false 是否需要UV
191
+ * @param {boolean} withColors=false 是否需要Colors
192
+ * @param {boolean} withColors=true 面使用点索引
193
+ * @returns {string | DataView} 返回文件内容
194
+ */
195
+ export function writePLY(polyData, format, dataByteOrder = DEFAULT_VALUES.dataByteOrder, headerComments = DEFAULT_VALUES.headerComments, textureFileName = DEFAULT_VALUES.textureFileName, textureCoordinatesName = DEFAULT_VALUES.textureCoordinatesName, withNormals = DEFAULT_VALUES.withNormals, withUVs = DEFAULT_VALUES.withUVs, withColors = DEFAULT_VALUES.withColors, withIndices = DEFAULT_VALUES.withIndices) {
196
+ var inPts = polyData.getPoints();
197
+ var polys = polyData.getPolys();
198
+
199
+ if (inPts === null || polys === null) {
200
+ console.error('输入错误!')
201
+ }
202
+
203
+ var writer = null;
204
+
205
+ if (format === 'binary') {
206
+ writer = binaryWriter();
207
+ } else if (format === 'ascii') {
208
+ writer = asciiWriter();
209
+ } else {
210
+ console.error('Invalid type format');
211
+ }
212
+
213
+ var tCoordsName = textureCoordinatesName;
214
+
215
+ if (typeof textureCoordinatesName === 'undefined') {
216
+ console.log('Invalid TextureCoordinatesName value, fallback to default uv values');
217
+ tCoordsName = TextureCoordinatesName.UV;
218
+ }
219
+
220
+ writer.init(polyData);
221
+ var numPts = inPts.getNumberOfPoints();
222
+ var numPolys = polys.getNumberOfCells(); // textureCoords / uvs
223
+
224
+ var textureCoords = polyData.getPointData().getTCoords(); // eslint-disable-next-line no-param-reassign
225
+
226
+ // withUVs = !(textureCoords === null); // scalars / colors
227
+
228
+ var scalars = polyData.getPointData().getScalars(); // eslint-disable-next-line no-param-reassign
229
+
230
+ withColors = !(scalars === null);
231
+ var fileType = dataByteOrder ? 0 : 1;
232
+ writer.writeHeader(polyData, format, fileType, headerComments, textureFileName, tCoordsName, numPts, numPolys, withNormals, withUVs, withColors, withIndices);
233
+ var normals = polyData.getPointData().getNormals(); // points / vertices
234
+
235
+ for (var i = 0; i < numPts; i++) {
236
+ // eslint-disable-next-line prefer-const
237
+ var p = inPts.getPoint(i);
238
+ // divide by 1 to remove trailing zeros
239
+
240
+
241
+ var x = p[0].toFixed(8);
242
+ var y = p[1].toFixed(8);
243
+ var z = p[2].toFixed(8); // normals
244
+
245
+ var nx = null;
246
+ var ny = null;
247
+ var nz = null; // uvs
248
+
249
+ var u = null;
250
+ var v = null; // colors
251
+
252
+ var r = null;
253
+ var g = null;
254
+ var b = null;
255
+
256
+ // if (textureCoords) {
257
+ // u = textureCoords.getData()[i * 2];
258
+ // v = textureCoords.getData()[i * 2 + 1];
259
+ // }
260
+
261
+ if (scalars) {
262
+ r = scalars.getData()[i * 3];
263
+ g = scalars.getData()[i * 3 + 1];
264
+ b = scalars.getData()[i * 3 + 2];
265
+ }
266
+
267
+ if (normals) {
268
+ nx = normals.getData()[i * 2];
269
+ ny = normals.getData()[i * 2 + 1];
270
+ nz = normals.getData()[i * 2 + 2];
271
+ }
272
+
273
+ writer.writeVertice(x, y, z, nx, ny, nz, u, v, r, g, b);
274
+ } // polys / indices
275
+
276
+
277
+ var pd = polys.getData();
278
+
279
+ for (var _i = 0, l = pd.length; _i < l; _i += 4) {
280
+ writer.writeFace(pd[_i + 0], pd[_i + 1], pd[_i + 2], pd[_i + 3]);
281
+ }
282
+
283
+ writer.writeFooter(polyData);
284
+ return writer.getOutputData();
285
+ }