xl-public-utils 1.0.22 → 1.0.24
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.d.ts +19 -128
- package/package.json +1 -5
- package/src/drcUtils.js +1 -3
- package/src/exportPLY.js +0 -1
- package/src/exportSTL.js +0 -1
- package/src/meshUtils.js +11 -11
- package/src/threeFont/index.js +37 -74
- package/src/vtkUtils.js +104 -238
- package/types/drcUtils.d.ts +3 -4
- package/types/exportPLY.d.ts +1 -2
- package/types/exportSTL.d.ts +2 -3
- package/types/vtkUtils.d.ts +5 -70
package/index.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
|
|
2
|
-
import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer";
|
|
3
1
|
import { mat3, mat4, vec3 } from "gl-matrix";
|
|
4
|
-
import vtkInteractorStyleManipulator from "@kitware/vtk.js/Interaction/Style/InteractorStyleManipulator.js"
|
|
5
|
-
import vtkRenderWindowInteractor from "@kitware/vtk.js/Rendering/Core/RenderWindowInteractor.js";
|
|
6
|
-
import { TypedArray } from "@kitware/vtk.js/types";
|
|
7
2
|
|
|
8
3
|
declare module "xl-public-utils" {
|
|
9
4
|
|
|
@@ -68,34 +63,6 @@ declare module "xl-public-utils" {
|
|
|
68
63
|
}
|
|
69
64
|
|
|
70
65
|
export namespace vtkUtils {
|
|
71
|
-
/**
|
|
72
|
-
* 计算屏幕坐标到三维坐标
|
|
73
|
-
* @param {vtkRenderer} renderer vtkRenderer
|
|
74
|
-
* @param {number} x display x position
|
|
75
|
-
* @param {number} y display y position
|
|
76
|
-
* @param {number} z display z position
|
|
77
|
-
* @returns {[number, number, number]} 三维坐标
|
|
78
|
-
*/
|
|
79
|
-
export function computeDisplayToWorld(
|
|
80
|
-
renderer: vtkRenderer,
|
|
81
|
-
x: number,
|
|
82
|
-
y: number,
|
|
83
|
-
z: number
|
|
84
|
-
): [number, number, number];
|
|
85
|
-
/**
|
|
86
|
-
* 计算三维坐标到屏幕坐标
|
|
87
|
-
* @param {vtkRenderer} renderer vtkRenderer
|
|
88
|
-
* @param {number} x 三维坐标 x值
|
|
89
|
-
* @param {number} y 三维坐标 y值
|
|
90
|
-
* @param {number} z 三维坐标 z值
|
|
91
|
-
* @returns {[number, number, number]} 屏幕坐标
|
|
92
|
-
*/
|
|
93
|
-
export function computeWorldToDisplay(
|
|
94
|
-
renderer: vtkRenderer,
|
|
95
|
-
x: number,
|
|
96
|
-
y: number,
|
|
97
|
-
z: number
|
|
98
|
-
): [number, number, number];
|
|
99
66
|
/**
|
|
100
67
|
* 计算 w2l(word 2 local, word to local) 的变换矩阵
|
|
101
68
|
* @param {vec3} center 中心点
|
|
@@ -124,29 +91,6 @@ declare module "xl-public-utils" {
|
|
|
124
91
|
yaxis: vec3,
|
|
125
92
|
zaxis: vec3
|
|
126
93
|
): mat4;
|
|
127
|
-
/**
|
|
128
|
-
* 返回交互的interactorStyle
|
|
129
|
-
* @returns {vtkInteractorStyleManipulator} 交互的interactorStyle
|
|
130
|
-
*/
|
|
131
|
-
export function make3DInteractorStyle(): vtkInteractorStyleManipulator;
|
|
132
|
-
/**
|
|
133
|
-
* 移除并返回当前renderWindow的所有鼠标交互设定
|
|
134
|
-
* @param {vtkRenderWindowInteractor} interactor vtkRenderWindowInteractor
|
|
135
|
-
* @returns {any[]} 当前鼠标的所有交互Manipulators
|
|
136
|
-
*/
|
|
137
|
-
export function removeMouseInteraction(
|
|
138
|
-
interactor: vtkRenderWindowInteractor
|
|
139
|
-
): any[];
|
|
140
|
-
/**
|
|
141
|
-
* 给当前窗口设置交互Maintainers
|
|
142
|
-
* @param {vtkRenderWindowInteractor} interactor vtkRenderWindowInteractor
|
|
143
|
-
* @param {any[]} mm 所有的交互Maintainers
|
|
144
|
-
* @returns {void}
|
|
145
|
-
*/
|
|
146
|
-
export function resetAllMouseMaintainers(
|
|
147
|
-
interactor: vtkRenderWindowInteractor,
|
|
148
|
-
mm: any[]
|
|
149
|
-
): void;
|
|
150
94
|
/**
|
|
151
95
|
* 将点投影到平面上
|
|
152
96
|
* @param {vec3} point 需要投影的点
|
|
@@ -245,9 +189,9 @@ declare module "xl-public-utils" {
|
|
|
245
189
|
/**
|
|
246
190
|
* 对一个polydata应用矩阵变化,直接改变点位置
|
|
247
191
|
* @param {mat4} mt4 变换矩阵
|
|
248
|
-
* @param {
|
|
192
|
+
* @param {number[]} vertices 需要应用变换的polydata
|
|
249
193
|
*/
|
|
250
|
-
export function
|
|
194
|
+
export function verticesApplyMat4(mt4: mat4, vertices: number[]): Float32Array;
|
|
251
195
|
/**
|
|
252
196
|
* 将点应用矩阵变换
|
|
253
197
|
* @param {vec3} point 三维点
|
|
@@ -269,7 +213,7 @@ declare module "xl-public-utils" {
|
|
|
269
213
|
* @returns {Blob} 网格的ply文件Blob
|
|
270
214
|
*/
|
|
271
215
|
export function createPlyBlob(
|
|
272
|
-
mesh:
|
|
216
|
+
mesh: any,
|
|
273
217
|
format?: "ascii" | "binary"
|
|
274
218
|
): Blob;
|
|
275
219
|
/**
|
|
@@ -277,7 +221,7 @@ declare module "xl-public-utils" {
|
|
|
277
221
|
* @param {vtkPolyData} mesh 网格polydata
|
|
278
222
|
* @returns {Blob} 网格的BinarySTL文件Blob
|
|
279
223
|
*/
|
|
280
|
-
export function createStlBlob(mesh:
|
|
224
|
+
export function createStlBlob(mesh: any): Blob;
|
|
281
225
|
/**
|
|
282
226
|
* 将网格压缩为drc文件,导出drc需要先加载draco_encode.js,并调用initDrcCoder初始化
|
|
283
227
|
* @param {vtkPolyData} mesh 网格文件
|
|
@@ -285,7 +229,7 @@ declare module "xl-public-utils" {
|
|
|
285
229
|
* @returns {Blob} drc文件
|
|
286
230
|
*/
|
|
287
231
|
export function createDrcBlob(
|
|
288
|
-
mesh:
|
|
232
|
+
mesh: any,
|
|
289
233
|
byteLength?: number
|
|
290
234
|
): Blob;
|
|
291
235
|
/**
|
|
@@ -305,7 +249,7 @@ declare module "xl-public-utils" {
|
|
|
305
249
|
* @returns {Blob} 对应类型的Blob
|
|
306
250
|
*/
|
|
307
251
|
export function createMeshTypeBlob(
|
|
308
|
-
mesh:
|
|
252
|
+
mesh: any,
|
|
309
253
|
type: "ply" | "stl" | "drc"
|
|
310
254
|
): Blob;
|
|
311
255
|
/**
|
|
@@ -386,14 +330,6 @@ declare module "xl-public-utils" {
|
|
|
386
330
|
yangle: number,
|
|
387
331
|
zangle: number
|
|
388
332
|
): mat3;
|
|
389
|
-
/**
|
|
390
|
-
* 将polyData转换为Base64string
|
|
391
|
-
* @param {vtkPolyData} mesh 网格数据
|
|
392
|
-
* @param {mat4} [matrix] 变换矩阵
|
|
393
|
-
* @param {number} byteLength=14 压缩率
|
|
394
|
-
* @returns {string} drc压缩之后的网格base64
|
|
395
|
-
*/
|
|
396
|
-
export function enCodeMeshToBase64(mesh: vtkPolyData,matrix?: mat4,byteLength?: number): string;
|
|
397
333
|
/**
|
|
398
334
|
* 将polyData转换为Base64string
|
|
399
335
|
* @param {Mesh} mesh 网格数据
|
|
@@ -465,35 +401,19 @@ declare module "xl-public-utils" {
|
|
|
465
401
|
zaxis: vec3
|
|
466
402
|
): mat4;
|
|
467
403
|
/**
|
|
468
|
-
*
|
|
469
|
-
* @param {
|
|
470
|
-
* @
|
|
404
|
+
* 顶点去重,用于 STL
|
|
405
|
+
* @param {Float32Array} vertices 输入顶点数组 [x,y,z, x,y,z, ...]
|
|
406
|
+
* @param {Int32Array} faces 输入面索引数组 [3,i1,i2,i3, 3,i4,i5,i6, ...]
|
|
407
|
+
* @param {number} [precision=1e-10] 精度,用于判断顶点相等(默认 1e-10)
|
|
408
|
+
* @returns {{ vertices: Float32Array, faces: Int32Array }} 去重后的网格数据
|
|
471
409
|
*/
|
|
472
|
-
export function
|
|
410
|
+
export function deduplicateVF(vertices: Float32Array | number[], faces: Int32Array | number[], precision?: number): { vertices: Float32Array, faces: Int32Array };
|
|
473
411
|
/**
|
|
474
412
|
* 判断一个矩阵是否是正交矩阵
|
|
475
413
|
* @param {mat4} matrix 矩阵
|
|
476
414
|
* @returns {boolean} 是否是正交矩阵
|
|
477
415
|
*/
|
|
478
416
|
export function isRotationMatrix(matrix: mat4): boolean;
|
|
479
|
-
/**
|
|
480
|
-
* 将vtkPolyData进行三角化
|
|
481
|
-
* @param {vtkPolyData} _polydata 需要三角化的vtkPolydata
|
|
482
|
-
* @returns {vtkPolyData} 三角化之后的vtkPolydata
|
|
483
|
-
*/
|
|
484
|
-
export function trianglePolys(_polydata: vtkPolyData): vtkPolyData;
|
|
485
|
-
/**
|
|
486
|
-
* 加载网格
|
|
487
|
-
* @param {string | File | Blob} file 文件或者文件链接
|
|
488
|
-
* @param {'drc' | 'stl' | 'ply'} [type] 文件类型,当file为string | File的时候可以不传根据文件后缀自动获取,drc需要先进行初始化
|
|
489
|
-
* @param {boolean} [process] 是否需要预先对数据进行处理,stl默认(去重)
|
|
490
|
-
* @returns {Promise<vtkPolyData>} vtkPolyData
|
|
491
|
-
*/
|
|
492
|
-
export function loadMeshData(
|
|
493
|
-
file: string | File | Blob,
|
|
494
|
-
type?: "drc" | "stl" | "ply",
|
|
495
|
-
process?: boolean
|
|
496
|
-
): Promise<vtkPolyData>;
|
|
497
417
|
/**
|
|
498
418
|
* @typedef Plane
|
|
499
419
|
* @property {vec3} origin 对应vtk坐标系的x值
|
|
@@ -546,19 +466,6 @@ declare module "xl-public-utils" {
|
|
|
546
466
|
*/
|
|
547
467
|
normal: vec3;
|
|
548
468
|
};
|
|
549
|
-
/**
|
|
550
|
-
* 复制一个polydata,只复制点和面的数据
|
|
551
|
-
* @param {vtkPolyData} originalPolyData 原始的polydata
|
|
552
|
-
* @returns {vtkPolyData} 新的polydata
|
|
553
|
-
*/
|
|
554
|
-
export function clonePolyData(originalPolyData: vtkPolyData): vtkPolyData;
|
|
555
|
-
/**
|
|
556
|
-
* 根据点和面创建一个vtkPolydata
|
|
557
|
-
* @param {number[] | TypedArray} verts
|
|
558
|
-
* @param {number[] | TypedArray} faces
|
|
559
|
-
* @returns { vtkPolyData } 生成出来的vtkPolydata
|
|
560
|
-
*/
|
|
561
|
-
export function createPolyData(verts: number[] | TypedArray, faces: number[] | TypedArray): vtkPolyData
|
|
562
469
|
}
|
|
563
470
|
export namespace drcUtils {
|
|
564
471
|
export type AttrOption = {
|
|
@@ -674,18 +581,6 @@ declare module "xl-public-utils" {
|
|
|
674
581
|
* @property {number[][] | vec3[]} vertices 点信息
|
|
675
582
|
* @property {number[][] | vec3[]} faces 面信息
|
|
676
583
|
*/
|
|
677
|
-
/**
|
|
678
|
-
* 使用drc压缩网格信息
|
|
679
|
-
* @param {vtkPolyData} mesh
|
|
680
|
-
* @param {number} byteLength=14 压缩率
|
|
681
|
-
* @param {AttrOption} [attr] 其他需要压缩的属性
|
|
682
|
-
* @returns {Int8Array} 压缩之后的DRC数据
|
|
683
|
-
*/
|
|
684
|
-
export function enCodeMesh(
|
|
685
|
-
mesh: vtkPolyData,
|
|
686
|
-
byteLength?: number,
|
|
687
|
-
attr?: AttrOption
|
|
688
|
-
): Int8Array;
|
|
689
584
|
/**
|
|
690
585
|
* 使用drc压缩网格信息
|
|
691
586
|
* @param {Mesh} mesh
|
|
@@ -715,7 +610,7 @@ declare module "xl-public-utils" {
|
|
|
715
610
|
* @param { vec3 } axisX 朝向 X 轴,默认 [1, 0, 0]
|
|
716
611
|
* @param { vec3 } axisY 朝向 Y 轴,默认 [0, 1, 0]
|
|
717
612
|
* @param { vec3 } axisZ 朝向 Z 轴,默认 [0, 0, 1]
|
|
718
|
-
* @returns {
|
|
613
|
+
* @returns { vertices: Float32Array, faces: Int32Array } 点和面 六边形网格
|
|
719
614
|
*/
|
|
720
615
|
export function createHexagonPolydata(
|
|
721
616
|
rows:number,
|
|
@@ -727,7 +622,7 @@ declare module "xl-public-utils" {
|
|
|
727
622
|
axisX?: vec3,
|
|
728
623
|
axisY?: vec3,
|
|
729
624
|
axisZ?: vec3
|
|
730
|
-
):
|
|
625
|
+
): { vertices: Float32Array, faces: Int32Array }
|
|
731
626
|
}
|
|
732
627
|
|
|
733
628
|
export namespace utils {
|
|
@@ -1042,7 +937,7 @@ declare module "xl-public-utils" {
|
|
|
1042
937
|
private constructor(); // 使用单例模式
|
|
1043
938
|
static Mgr(): FontManager;
|
|
1044
939
|
|
|
1045
|
-
private cacheFontMap: Record<string,
|
|
940
|
+
private cacheFontMap: Record<string, {vertices: ArrayLike<number>, faces: ArrayLike<number>}>;
|
|
1046
941
|
private cacheFontPointMap: Record<string, IndexData>;
|
|
1047
942
|
private fontJsonMap: Record<string, any>;
|
|
1048
943
|
private parameters: FontParameters & { font: Record<string, any> };
|
|
@@ -1066,18 +961,14 @@ declare module "xl-public-utils" {
|
|
|
1066
961
|
fontName?: string,
|
|
1067
962
|
scale?: vec3
|
|
1068
963
|
): {
|
|
1069
|
-
|
|
1070
|
-
|
|
964
|
+
vertices: number[],
|
|
965
|
+
faces: number[],
|
|
966
|
+
indexData: IndexData,
|
|
1071
967
|
};
|
|
1072
968
|
|
|
1073
969
|
/**
|
|
1074
970
|
* 获取顶点索引映射
|
|
1075
971
|
*/
|
|
1076
|
-
getPointsMapData(polydata:
|
|
1077
|
-
|
|
1078
|
-
/**
|
|
1079
|
-
* 创建 vtkPolyData 对象
|
|
1080
|
-
*/
|
|
1081
|
-
createPolyData(verts: any, faces: any): vtkPolyData;
|
|
972
|
+
getPointsMapData(polydata: ArrayLike<number>): IndexData;
|
|
1082
973
|
}
|
|
1083
974
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xl-public-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.24",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.js",
|
|
@@ -14,13 +14,9 @@
|
|
|
14
14
|
"tsconfig.json"
|
|
15
15
|
],
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@kitware/vtk.js": ">=25.7.2",
|
|
18
17
|
"gl-matrix": ">=3.4.3"
|
|
19
18
|
},
|
|
20
19
|
"peerDependenciesMeta": {
|
|
21
|
-
"@kitware/vtk.js": {
|
|
22
|
-
"optional": true
|
|
23
|
-
},
|
|
24
20
|
"gl-matrix": {
|
|
25
21
|
"optional": true
|
|
26
22
|
}
|
package/src/drcUtils.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { vec3 } from "gl-matrix";
|
|
2
2
|
import { int8ArrayToBase64 } from './utils.js'
|
|
3
|
-
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
|
|
4
|
-
import vtkDracoReader from "@kitware/vtk.js/IO/Geometry/DracoReader";
|
|
5
3
|
/**
|
|
6
4
|
* @typedef {Object} AttrOption
|
|
7
5
|
* @property {number[]} [colors] 颜色数组
|
|
@@ -350,7 +348,7 @@ export function initDrcCoder() {
|
|
|
350
348
|
return res;
|
|
351
349
|
}
|
|
352
350
|
// show.value = true;
|
|
353
|
-
vtkDracoReader.setDracoDecoder(a);
|
|
351
|
+
// vtkDracoReader.setDracoDecoder(a);
|
|
354
352
|
});
|
|
355
353
|
clearInterval(timerDecoder);
|
|
356
354
|
}
|
package/src/exportPLY.js
CHANGED
package/src/exportSTL.js
CHANGED
package/src/meshUtils.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ExtrudeGeometry } from './threeFont/TextGeometry/ExtrudeGeometry.js';
|
|
2
2
|
import { Shape } from './threeFont/Curve/Shape.js';
|
|
3
3
|
import { vec3, mat4 } from 'gl-matrix';
|
|
4
|
-
import
|
|
5
|
-
import { clonePolyData, createPolyData, getL2WMatrix, getPolydataCenterOffset, mergePolyData, pointsApplyMat4 } from './vtkUtils.js';
|
|
4
|
+
import { getL2WMatrix, getPolydataCenterOffset, mergeMeshes, verticesApplyMat4 } from './vtkUtils.js';
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -60,7 +59,7 @@ export function createHexagonGeometry(radius, height, wallThickness) {
|
|
|
60
59
|
* @param { vec3 } axisX 朝向 X 轴,默认 [1, 0, 0]
|
|
61
60
|
* @param { vec3 } axisY 朝向 Y 轴,默认 [0, 1, 0]
|
|
62
61
|
* @param { vec3 } axisZ 朝向 Z 轴,默认 [0, 0, 1]
|
|
63
|
-
* @returns {
|
|
62
|
+
* @returns { vertices: Float32Array, faces: Int32Array } 点和面 六边形网格
|
|
64
63
|
*/
|
|
65
64
|
export function createHexagonPolydata(
|
|
66
65
|
rows,
|
|
@@ -81,30 +80,31 @@ export function createHexagonPolydata(
|
|
|
81
80
|
const b = (radius / 2) * z - _wall / 2 / z;
|
|
82
81
|
|
|
83
82
|
const geometry = createHexagonGeometry(radius, height, _wall);
|
|
84
|
-
const polyData = createPolyData(geometry.vertices, geometry.faces);
|
|
85
83
|
|
|
86
84
|
let polyDataArr = [];
|
|
87
85
|
// 生成网格
|
|
88
86
|
for (let i = 0; i < rows; i++) {
|
|
89
87
|
let q = i % 2; // 奇偶行偏移
|
|
90
88
|
for (let j = 1; j <= cols; j++) {
|
|
91
|
-
let _polyData = clonePolyData(polyData);
|
|
92
89
|
|
|
93
90
|
// 根据形状和OpenSCAD公式计算位置
|
|
94
91
|
let x = i * a;
|
|
95
92
|
let y = j * b * 2 + q * b - b;
|
|
96
93
|
let _trans = mat4.fromTranslation(mat4.create(), [x, y, 0]);
|
|
97
|
-
|
|
98
|
-
polyDataArr.push(
|
|
94
|
+
const newVertices = verticesApplyMat4(_trans, geometry.vertices);
|
|
95
|
+
polyDataArr.push({
|
|
96
|
+
vertices: newVertices,
|
|
97
|
+
faces: geometry.faces
|
|
98
|
+
});
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
const resultPolyData =
|
|
103
|
-
const _offset = getPolydataCenterOffset(resultPolyData);
|
|
102
|
+
const resultPolyData = mergeMeshes(polyDataArr);
|
|
103
|
+
const _offset = getPolydataCenterOffset(resultPolyData.vertices);
|
|
104
104
|
const offsetM4 = mat4.translate(mat4.create(), mat4.create(), [_offset.x, _offset.y, 0]);
|
|
105
|
-
|
|
105
|
+
resultPolyData.vertices = verticesApplyMat4(offsetM4, resultPolyData.vertices);
|
|
106
106
|
|
|
107
107
|
const _matrix = getL2WMatrix(center, axisX, axisY, axisZ);
|
|
108
|
-
|
|
108
|
+
resultPolyData.vertices = verticesApplyMat4(_matrix, resultPolyData.vertices);
|
|
109
109
|
return resultPolyData;
|
|
110
110
|
}
|
package/src/threeFont/index.js
CHANGED
|
@@ -2,14 +2,10 @@ import { Font } from './TextGeometry/FontLoader.js';
|
|
|
2
2
|
import { ExtrudeGeometry } from './TextGeometry/ExtrudeGeometry.js';
|
|
3
3
|
import { mat4, vec3 } from 'gl-matrix';
|
|
4
4
|
|
|
5
|
-
import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData.js';
|
|
6
|
-
import vtkPoints from '@kitware/vtk.js/Common/Core/Points.js';
|
|
7
|
-
import vtkCellArray from '@kitware/vtk.js/Common/Core/CellArray.js';
|
|
8
5
|
|
|
9
6
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
pointsApplyMat4
|
|
7
|
+
deduplicateVF,
|
|
8
|
+
verticesApplyMat4
|
|
13
9
|
} from '../vtkUtils.js';
|
|
14
10
|
|
|
15
11
|
/**
|
|
@@ -21,7 +17,7 @@ class FontManager {
|
|
|
21
17
|
constructor() {
|
|
22
18
|
if (FontManager.instance) return FontManager.instance;
|
|
23
19
|
|
|
24
|
-
/** @type {Object.<string,
|
|
20
|
+
/** @type {Object.<string, {vertices: ArrayLike<number>, faces: ArrayLike<number>}}>} */
|
|
25
21
|
this.cacheFontMap = {};
|
|
26
22
|
/** @type {Object.<string, { zeroIndexs: number[], oneIndexs: number[] }>} */
|
|
27
23
|
this.cacheFontPointMap = {};
|
|
@@ -68,48 +64,44 @@ class FontManager {
|
|
|
68
64
|
* @param {string} text
|
|
69
65
|
* @param {string} fontName
|
|
70
66
|
* @param {vec3} scale
|
|
71
|
-
* @returns {{
|
|
67
|
+
* @returns {{ vertices: ArrayLike<number>, faces: ArrayLike<number>, indexData: { zeroIndexs: number[], oneIndexs: number[] } }}
|
|
72
68
|
*/
|
|
73
69
|
generateShapes(text, fontName = 'defaultFont', scale = [0.018, 0.018, 0.018]) {
|
|
74
70
|
const scaleM4 = mat4.scale(mat4.create(), mat4.create(), scale);
|
|
75
71
|
|
|
76
72
|
if (this.cacheFontMap[text]) {
|
|
77
|
-
const
|
|
78
|
-
pointsApplyMat4(scaleM4, newPolyData);
|
|
73
|
+
const newVertices = verticesApplyMat4(scaleM4, this.cacheFontMap[text].vertices);
|
|
79
74
|
return {
|
|
80
|
-
|
|
75
|
+
vertices: newVertices,
|
|
76
|
+
faces: this.cacheFontMap[text].faces,
|
|
81
77
|
indexData: this.cacheFontPointMap[text]
|
|
82
78
|
};
|
|
83
79
|
}
|
|
84
80
|
|
|
85
81
|
const shapes = this.parameters.font[fontName].generateShapes(text, this.parameters.size);
|
|
86
82
|
const extrude = new ExtrudeGeometry(shapes, this.parameters);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
polyData = this.reIndexPolyData(polyData);
|
|
91
|
-
const indexData = this.getPointsMapData(polyData);
|
|
83
|
+
let vfData = deduplicateVF(extrude.vertices, extrude.faces);
|
|
84
|
+
vfData = this.reIndexByVF(vfData.vertices, vfData.faces);
|
|
85
|
+
const indexData = this.getPointsMapData(vfData.vertices);
|
|
92
86
|
// console.log(indexData);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
pointsApplyMat4(scaleM4, _polyData);
|
|
96
|
-
|
|
97
|
-
this.cacheFontMap[text] = polyData;
|
|
87
|
+
const newVertices = verticesApplyMat4(scaleM4, vfData.vertices);
|
|
88
|
+
this.cacheFontMap[text] = vfData;
|
|
98
89
|
this.cacheFontPointMap[text] = indexData;
|
|
99
90
|
|
|
100
91
|
return {
|
|
101
|
-
|
|
92
|
+
vertices: newVertices,
|
|
93
|
+
faces: vfData.faces,
|
|
102
94
|
indexData
|
|
103
95
|
};
|
|
104
96
|
}
|
|
105
97
|
|
|
106
98
|
/**
|
|
107
|
-
*
|
|
108
|
-
* @param {
|
|
99
|
+
* 根据指定索引集合重新组织点和面
|
|
100
|
+
* @param {Float32Array} vertices 点数组 [x,y,z, x,y,z, ...]
|
|
109
101
|
* @returns {{ zeroIndexs: number[], oneIndexs: number[] }}
|
|
110
102
|
*/
|
|
111
|
-
getPointsMapData(
|
|
112
|
-
const points =
|
|
103
|
+
getPointsMapData(vertices) {
|
|
104
|
+
const points = vertices
|
|
113
105
|
const zeroIndexs = [];
|
|
114
106
|
const oneIndexs = [];
|
|
115
107
|
const pointIndexMap = {};
|
|
@@ -137,65 +129,36 @@ class FontManager {
|
|
|
137
129
|
};
|
|
138
130
|
}
|
|
139
131
|
/**
|
|
140
|
-
*
|
|
141
|
-
* @param {
|
|
142
|
-
* @
|
|
132
|
+
* 根据指定索引集合重新组织点和面
|
|
133
|
+
* @param {Float32Array} vertices 点数组 [x,y,z, x,y,z, ...]
|
|
134
|
+
* @param {Int32Array} faces 面索引数组 (VTK风格: [3,i1,i2,i3, 3,i4,i5,i6,...])
|
|
143
135
|
*/
|
|
144
|
-
|
|
145
|
-
const indexData = this.getPointsMapData(
|
|
136
|
+
reIndexByVF(vertices, faces) {
|
|
137
|
+
const indexData = this.getPointsMapData(vertices);
|
|
146
138
|
const allIndexData = [...indexData.zeroIndexs, ...indexData.oneIndexs]
|
|
147
|
-
const
|
|
148
|
-
const nowFaces = polydata.getPolys().getData();
|
|
149
|
-
const newPoints = new Float32Array(nowPoints.length);
|
|
139
|
+
const newPoints = new Float32Array(vertices.length);
|
|
150
140
|
const indexMap = {};
|
|
151
141
|
for(let i = 0; i < allIndexData.length; i++) {
|
|
152
142
|
const index = allIndexData[i];
|
|
153
|
-
const x =
|
|
154
|
-
const y =
|
|
155
|
-
const z =
|
|
143
|
+
const x = vertices[index * 3];
|
|
144
|
+
const y = vertices[index * 3 + 1];
|
|
145
|
+
const z = vertices[index * 3 + 2];
|
|
156
146
|
newPoints[i * 3] = x
|
|
157
147
|
newPoints[i * 3 + 1] = y
|
|
158
148
|
newPoints[i * 3 + 2] = z
|
|
159
149
|
indexMap[index] = i;
|
|
160
150
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
nowFaces[i + 3] = indexMap[p3]
|
|
151
|
+
const newFaces = new Int32Array(faces.length);
|
|
152
|
+
for(let i =0; i< faces.length; i += 4) {
|
|
153
|
+
newFaces[i] = 3;
|
|
154
|
+
newFaces[i + 1] = indexMap[faces[i + 1]];
|
|
155
|
+
newFaces[i + 2] = indexMap[faces[i + 2]];
|
|
156
|
+
newFaces[i + 3] = indexMap[faces[i + 3]];
|
|
168
157
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* 创建 vtkPolyData 对象
|
|
176
|
-
* @param {any} verts
|
|
177
|
-
* @param {any} faces
|
|
178
|
-
* @returns {vtkPolyData}
|
|
179
|
-
*/
|
|
180
|
-
createPolyData(verts, faces) {
|
|
181
|
-
const values_v = Object.values(verts);
|
|
182
|
-
const values_f = Object.values(faces);
|
|
183
|
-
|
|
184
|
-
const _verts = values_v.map(v => parseFloat(v));
|
|
185
|
-
const _faces = values_f.map(f => parseInt(f));
|
|
186
|
-
|
|
187
|
-
const vpoints = vtkPoints.newInstance();
|
|
188
|
-
const cellArray = vtkCellArray.newInstance();
|
|
189
|
-
|
|
190
|
-
vpoints.setData(_verts, 3);
|
|
191
|
-
cellArray.setNumberOfComponents(4);
|
|
192
|
-
cellArray.setData(_faces);
|
|
193
|
-
|
|
194
|
-
const polyData = vtkPolyData.newInstance();
|
|
195
|
-
polyData.setPoints(vpoints);
|
|
196
|
-
polyData.setPolys(cellArray);
|
|
197
|
-
|
|
198
|
-
return polyData;
|
|
158
|
+
return {
|
|
159
|
+
vertices: newPoints,
|
|
160
|
+
faces: newFaces,
|
|
161
|
+
};
|
|
199
162
|
}
|
|
200
163
|
}
|
|
201
164
|
|
package/src/vtkUtils.js
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer.js";
|
|
2
|
-
import vtkInteractorStyleManipulator from "@kitware/vtk.js/Interaction/Style/InteractorStyleManipulator.js"
|
|
3
|
-
import vtkMouseCameraTrackballPanManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js";
|
|
4
|
-
import vtkMouseCameraTrackballRotateManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js";
|
|
5
|
-
import vtkMouseCameraTrackballZoomManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballZoomManipulator.js";
|
|
6
|
-
import vtkRenderWindowInteractor from "@kitware/vtk.js/Rendering/Core/RenderWindowInteractor.js";
|
|
7
|
-
import vtkMatrixBuilder from "@kitware/vtk.js/Common/Core/MatrixBuilder.js";
|
|
8
|
-
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
|
|
9
|
-
import vtkPLYReader from '@kitware/vtk.js/IO/Geometry/PLYReader';
|
|
10
|
-
import vtkSTLReader from '@kitware/vtk.js/IO/Geometry/STLReader';
|
|
11
|
-
import vtkDracoReader from '@kitware/vtk.js/IO/Geometry/DracoReader';
|
|
12
|
-
import vtkTriangleFilter from "@kitware/vtk.js/Filters/General/TriangleFilter";
|
|
13
|
-
import vtkPoints from '@kitware/vtk.js/Common/Core/Points';
|
|
14
|
-
import vtkCellArray from '@kitware/vtk.js/Common/Core/CellArray';
|
|
15
|
-
import vtkAppendPolyData from '@kitware/vtk.js/Filters/General/AppendPolyData';
|
|
16
1
|
import { vec3, mat4, mat3, quat } from 'gl-matrix';
|
|
17
2
|
import { exportBinarySTL } from './exportSTL.js';
|
|
18
3
|
import { writePLY } from "./exportPLY.js";
|
|
19
4
|
import { enCodeMesh } from './drcUtils.js';
|
|
20
|
-
import {
|
|
21
|
-
|
|
5
|
+
import { int8ArrayToBase64 } from "./utils.js";
|
|
22
6
|
/**
|
|
23
7
|
* 计算屏幕坐标到三维坐标
|
|
24
8
|
* @param {vtkRenderer} renderer vtkRenderer
|
|
@@ -153,42 +137,6 @@ export function getL2WMatrix(
|
|
|
153
137
|
*/
|
|
154
138
|
export const getmatofl2w = getL2WMatrix;
|
|
155
139
|
|
|
156
|
-
/**
|
|
157
|
-
* 返回交互的interactorStyle
|
|
158
|
-
* @returns {vtkInteractorStyleManipulator} 交互的interactorStyle
|
|
159
|
-
*/
|
|
160
|
-
export function make3DInteractorStyle() {
|
|
161
|
-
const interactorStyle = vtkInteractorStyleManipulator.newInstance();
|
|
162
|
-
const cameraRotate = vtkMouseCameraTrackballRotateManipulator.newInstance({
|
|
163
|
-
button: 1,
|
|
164
|
-
});
|
|
165
|
-
const cameraPan = vtkMouseCameraTrackballPanManipulator.newInstance({
|
|
166
|
-
button: 3,
|
|
167
|
-
});
|
|
168
|
-
// const cameraPanControl = vtkMouseCameraTrackballPanManipulator.newInstance({
|
|
169
|
-
// button: 1,
|
|
170
|
-
// shift: true,
|
|
171
|
-
// });
|
|
172
|
-
// const cameraRoll = vtkMouseCameraTrackballRollManipulator.newInstance({
|
|
173
|
-
// button: 3,
|
|
174
|
-
// control: true,
|
|
175
|
-
// });
|
|
176
|
-
const cameraZoom = vtkMouseCameraTrackballZoomManipulator.newInstance({
|
|
177
|
-
button: 2,
|
|
178
|
-
});
|
|
179
|
-
const cameraZoomDrag = vtkMouseCameraTrackballZoomManipulator.newInstance({
|
|
180
|
-
scrollEnabled: true,
|
|
181
|
-
dragEnabled: false,
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
interactorStyle.addMouseManipulator(cameraRotate);
|
|
185
|
-
interactorStyle.addMouseManipulator(cameraPan);
|
|
186
|
-
// interactorStyle.addMouseManipulator(cameraPanControl);
|
|
187
|
-
// interactorStyle.addMouseManipulator(cameraRoll);
|
|
188
|
-
// interactorStyle.addMouseManipulator(cameraZoom);
|
|
189
|
-
interactorStyle.addMouseManipulator(cameraZoomDrag);
|
|
190
|
-
return interactorStyle;
|
|
191
|
-
}
|
|
192
140
|
|
|
193
141
|
/**
|
|
194
142
|
* 移除并返回当前renderWindow的所有鼠标交互设定
|
|
@@ -390,16 +338,26 @@ export function getPointToPlaneDist(point, origin, normal) { // 如果法向量
|
|
|
390
338
|
|
|
391
339
|
|
|
392
340
|
/**
|
|
393
|
-
*
|
|
341
|
+
* 对点集合应用 4x4 变换矩阵
|
|
394
342
|
* @param {mat4} mt4 变换矩阵
|
|
395
|
-
* @param {
|
|
343
|
+
* @param {number[]} points 点数组 [x1,y1,z1, x2,y2,z2, ...]
|
|
344
|
+
* @returns {Float32Array} 变换后的点数组(新的数组,不改变原数组)
|
|
396
345
|
*/
|
|
346
|
+
export function verticesApplyMat4(mt4, points) {
|
|
347
|
+
const result = new Float32Array(points.length);
|
|
348
|
+
const v = vec3.create();
|
|
349
|
+
|
|
350
|
+
for (let i = 0; i < points.length; i += 3) {
|
|
351
|
+
v[0] = points[i];
|
|
352
|
+
v[1] = points[i + 1];
|
|
353
|
+
v[2] = points[i + 2];
|
|
354
|
+
vec3.transformMat4(v, v, mt4); // v = mt4 * v
|
|
355
|
+
result[i] = v[0];
|
|
356
|
+
result[i + 1] = v[1];
|
|
357
|
+
result[i + 2] = v[2];
|
|
358
|
+
}
|
|
397
359
|
|
|
398
|
-
|
|
399
|
-
vtkMatrixBuilder
|
|
400
|
-
.buildFromDegree()
|
|
401
|
-
.multiply(mt4)
|
|
402
|
-
.apply(data.getPoints().getData());
|
|
360
|
+
return result;
|
|
403
361
|
}
|
|
404
362
|
|
|
405
363
|
/**
|
|
@@ -489,64 +447,57 @@ export function createMeshTypeBlob(
|
|
|
489
447
|
}
|
|
490
448
|
}
|
|
491
449
|
|
|
492
|
-
|
|
493
450
|
/**
|
|
494
|
-
*
|
|
495
|
-
* @param {
|
|
496
|
-
* @
|
|
451
|
+
* 顶点去重,用于 STL
|
|
452
|
+
* @param {Float32Array} vertices 输入顶点数组 [x,y,z, x,y,z, ...]
|
|
453
|
+
* @param {Int32Array} faces 输入面索引数组 [3,i1,i2,i3, 3,i4,i5,i6, ...]
|
|
454
|
+
* @param {number} [precision=1e-10] 精度,用于判断顶点相等(默认 1e-10)
|
|
455
|
+
* @returns {{ vertices: Float32Array, faces: Int32Array }} 去重后的网格数据
|
|
497
456
|
*/
|
|
498
|
-
export function
|
|
499
|
-
const OFFSET_BOUNDS = 10
|
|
500
|
-
const vMap = new Map();
|
|
501
|
-
const vIndexMap = new Map();
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const colors = hasColorInfo
|
|
506
|
-
? data.getPointData().getScalars().getData()
|
|
507
|
-
: new Uint8Array(vertices.length);
|
|
508
|
-
let vInc = 0; // 顶点新索引
|
|
509
|
-
// 更新顶点map:vMap和顶点映射map:vIndexMap
|
|
457
|
+
export function deduplicateVF(vertices, faces, precision = 1e-10) {
|
|
458
|
+
const OFFSET_BOUNDS = Math.log10(1 / precision); // 比如 precision=1e-10 => 10
|
|
459
|
+
const vMap = new Map(); // key -> newIndex
|
|
460
|
+
const vIndexMap = new Map(); // oldIndex -> newIndex
|
|
461
|
+
let vInc = 0;
|
|
462
|
+
|
|
463
|
+
// 建立映射
|
|
510
464
|
for (let i = 0; i < vertices.length; i += 3) {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
vertices[i + 2] * Math.pow(10, OFFSET_BOUNDS)
|
|
516
|
-
).toFixed(0)}`;
|
|
517
|
-
if (vMap.get(key) !== undefined) {
|
|
465
|
+
const key = `${(vertices[i] * Math.pow(10, OFFSET_BOUNDS)).toFixed(0)},` +
|
|
466
|
+
`${(vertices[i + 1] * Math.pow(10, OFFSET_BOUNDS)).toFixed(0)},` +
|
|
467
|
+
`${(vertices[i + 2] * Math.pow(10, OFFSET_BOUNDS)).toFixed(0)}`;
|
|
468
|
+
if (vMap.has(key)) {
|
|
518
469
|
vIndexMap.set(i / 3, vMap.get(key));
|
|
519
470
|
} else {
|
|
520
|
-
vIndexMap.set(i / 3, vInc);
|
|
521
|
-
hasColorInfo && cMap.set(vInc, [colors[i], colors[i + 1], colors[i + 2]]);
|
|
522
471
|
vMap.set(key, vInc);
|
|
472
|
+
vIndexMap.set(i / 3, vInc);
|
|
523
473
|
vInc++;
|
|
524
474
|
}
|
|
525
475
|
}
|
|
476
|
+
|
|
477
|
+
// 重建顶点数组
|
|
526
478
|
const tVertices = new Float32Array(vMap.size * 3);
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
.map((e) => +e * Math.pow(10, -OFFSET_BOUNDS));
|
|
534
|
-
const t = cMap.get(vMap.get(k));
|
|
535
|
-
hasColorInfo && ([tColors[j], tColors[j + 1], tColors[j + 2]] = t);
|
|
479
|
+
for (const [key, idx] of vMap.entries()) {
|
|
480
|
+
const j = idx * 3;
|
|
481
|
+
const [x, y, z] = key.split(",").map((e) => +e * Math.pow(10, -OFFSET_BOUNDS));
|
|
482
|
+
tVertices[j] = x;
|
|
483
|
+
tVertices[j + 1] = y;
|
|
484
|
+
tVertices[j + 2] = z;
|
|
536
485
|
}
|
|
537
|
-
|
|
538
|
-
|
|
486
|
+
|
|
487
|
+
// 重建面索引
|
|
488
|
+
const tFaces = new Int32Array(faces.length);
|
|
539
489
|
for (let i = 0; i < faces.length; i += 4) {
|
|
540
|
-
tFaces[i] = 3;
|
|
490
|
+
tFaces[i] = 3; // 三角面
|
|
541
491
|
tFaces[i + 1] = vIndexMap.get(faces[i + 1]);
|
|
542
492
|
tFaces[i + 2] = vIndexMap.get(faces[i + 2]);
|
|
543
493
|
tFaces[i + 3] = vIndexMap.get(faces[i + 3]);
|
|
544
494
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
};
|
|
495
|
+
|
|
496
|
+
return {
|
|
497
|
+
vertices: tVertices,
|
|
498
|
+
faces: tFaces
|
|
499
|
+
};
|
|
500
|
+
}
|
|
550
501
|
|
|
551
502
|
/**
|
|
552
503
|
* 计算一组三维点的中心点
|
|
@@ -734,21 +685,13 @@ export function convEular2matrixZYX(rmat, xangle, yangle, zangle) {
|
|
|
734
685
|
|
|
735
686
|
/**
|
|
736
687
|
* 将polyData转换为Base64string
|
|
737
|
-
* @param {
|
|
688
|
+
* @param {Mesh} mesh 网格数据
|
|
738
689
|
* @param {mat4} [matrix] 变换矩阵
|
|
739
690
|
* @param {number} byteLength=14 压缩率
|
|
740
691
|
* @returns {string} drc压缩之后的网格base64
|
|
741
692
|
*/
|
|
742
693
|
export function enCodeMeshToBase64(mesh, matrix = undefined, byteLength = 14) {
|
|
743
|
-
|
|
744
|
-
const encodePolydata = vtkPolyData.newInstance();
|
|
745
|
-
encodePolydata.getPoints().setData([...mesh.getPoints().getData()]);
|
|
746
|
-
encodePolydata.getPolys().setData([...mesh.getPolys().getData()]);
|
|
747
|
-
pointsApplyMat4(matrix, encodePolydata);
|
|
748
|
-
return int8ArrayToBase64(enCodeMesh(encodePolydata, byteLength))
|
|
749
|
-
} else {
|
|
750
|
-
return int8ArrayToBase64(enCodeMesh(mesh, byteLength))
|
|
751
|
-
}
|
|
694
|
+
return int8ArrayToBase64(enCodeMesh(mesh, byteLength))
|
|
752
695
|
}
|
|
753
696
|
|
|
754
697
|
/**
|
|
@@ -869,74 +812,6 @@ export function isRotationMatrix(matrix) {
|
|
|
869
812
|
return true;
|
|
870
813
|
}
|
|
871
814
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* 将vtkPolyData进行三角化
|
|
876
|
-
* @param {vtkPolyData} polydata 需要三角化的vtkPolydata
|
|
877
|
-
* @returns {vtkPolyData} 三角化之后的vtkPolydata
|
|
878
|
-
*/
|
|
879
|
-
export function trianglePolys(polydata) {
|
|
880
|
-
const triangleFilter = vtkTriangleFilter.newInstance();
|
|
881
|
-
triangleFilter.setInputData(polydata);
|
|
882
|
-
return triangleFilter.getOutputData();
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
/**
|
|
887
|
-
* 加载网格
|
|
888
|
-
* @param {string | File | Blob} file 文件或者文件链接
|
|
889
|
-
* @param {'drc' | 'stl' | 'ply'} [type] 文件类型,当file为string | File的时候可以不传根据文件后缀自动获取,drc需要先进行初始化
|
|
890
|
-
* @param {boolean} [process] 是否需要预先对数据进行处理,stl默认(去重)
|
|
891
|
-
* @returns {Promise<vtkPolyData>} vtkPolyData
|
|
892
|
-
*/
|
|
893
|
-
export async function loadMeshData(file, type = undefined, process = undefined) {
|
|
894
|
-
let _fileBuffer;
|
|
895
|
-
if(typeof file === 'string') {
|
|
896
|
-
type = getFileExtension(file);
|
|
897
|
-
const _file = await fetch(file)
|
|
898
|
-
_fileBuffer = await _file.arrayBuffer()
|
|
899
|
-
} else if(file instanceof Blob && type !== undefined) {
|
|
900
|
-
_fileBuffer = await file.arrayBuffer();
|
|
901
|
-
} else if(file instanceof File) {
|
|
902
|
-
_fileBuffer = await file.arrayBuffer();
|
|
903
|
-
if(!type) {
|
|
904
|
-
type = getFileExtension(file.name);
|
|
905
|
-
}
|
|
906
|
-
} else {
|
|
907
|
-
throw('error: file type error')
|
|
908
|
-
}
|
|
909
|
-
/** @type {vtkPLYReader | vtkSTLReader | vtkDracoReader} */
|
|
910
|
-
let reader;
|
|
911
|
-
switch (type) {
|
|
912
|
-
case 'ply':
|
|
913
|
-
reader = vtkPLYReader.newInstance();
|
|
914
|
-
if(process === undefined) {
|
|
915
|
-
process = false;
|
|
916
|
-
}
|
|
917
|
-
break;
|
|
918
|
-
case 'stl':
|
|
919
|
-
reader = vtkSTLReader.newInstance();
|
|
920
|
-
if(process === undefined) {
|
|
921
|
-
process = true;
|
|
922
|
-
}
|
|
923
|
-
break;
|
|
924
|
-
case 'drc':
|
|
925
|
-
reader = vtkDracoReader.newInstance();
|
|
926
|
-
break;
|
|
927
|
-
default:
|
|
928
|
-
throw('error: file type error')
|
|
929
|
-
}
|
|
930
|
-
reader.parseAsArrayBuffer(_fileBuffer);
|
|
931
|
-
let polyData = reader.getOutputData();
|
|
932
|
-
if(process) {
|
|
933
|
-
if(type === 'stl') {
|
|
934
|
-
return deduplicatePolyData(polyData);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
return polyData;
|
|
938
|
-
}
|
|
939
|
-
|
|
940
815
|
/**
|
|
941
816
|
* @typedef Plane
|
|
942
817
|
* @property {vec3} origin 对应vtk坐标系的x值
|
|
@@ -1030,77 +905,68 @@ export function getCurvePointIndexByLength(points, dist, absDist = true) {
|
|
|
1030
905
|
const targetIndex = targetDistanceSubs.findIndex(i => i === minSub)
|
|
1031
906
|
return targetIndex;
|
|
1032
907
|
}
|
|
1033
|
-
|
|
1034
908
|
/**
|
|
1035
|
-
*
|
|
1036
|
-
* @param {
|
|
1037
|
-
*
|
|
909
|
+
* 合并多个 mesh
|
|
910
|
+
* @param {Array<{ vertices: Float32Array, faces: Uint32Array }>} meshes
|
|
911
|
+
* - vertices: Float32Array,长度 = 顶点数 * 3
|
|
912
|
+
* - faces: Uint32Array 或 Int32Array,格式为 [n, i1, i2, i3, n, j1, j2, j3, ...] (和 vtkPolyData.getPolys().getData() 一样)
|
|
913
|
+
* @returns {{ vertices: Float32Array, faces: Uint32Array }}
|
|
1038
914
|
*/
|
|
1039
|
-
export function
|
|
1040
|
-
//
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
clonedPolyData.getPolys().setData([...originalCells]);
|
|
1048
|
-
return clonedPolyData;
|
|
1049
|
-
}
|
|
915
|
+
export function mergeMeshes(meshes) {
|
|
916
|
+
// 先算总点数和总面索引数
|
|
917
|
+
let totalPoints = 0;
|
|
918
|
+
let totalFaces = 0;
|
|
919
|
+
meshes.forEach(mesh => {
|
|
920
|
+
totalPoints += mesh.vertices.length;
|
|
921
|
+
totalFaces += mesh.faces.length;
|
|
922
|
+
});
|
|
1050
923
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
polyData.setPolys(cellArray);
|
|
1075
|
-
return polyData;
|
|
1076
|
-
}
|
|
924
|
+
// 合并数组
|
|
925
|
+
const mergedPoints = new Float32Array(totalPoints);
|
|
926
|
+
const mergedFaces = new Uint32Array(totalFaces);
|
|
927
|
+
|
|
928
|
+
let pointOffset = 0; // 顶点偏移量 (按点坐标数量, 即 *3 后的下标)
|
|
929
|
+
let faceOffset = 0; // 面的写入位置
|
|
930
|
+
let indexOffset = 0; // 索引偏移量 (按顶点数量)
|
|
931
|
+
|
|
932
|
+
for (const mesh of meshes) {
|
|
933
|
+
// 复制点
|
|
934
|
+
mergedPoints.set(mesh.vertices, pointOffset);
|
|
935
|
+
|
|
936
|
+
// faces 要改索引
|
|
937
|
+
const faces = mesh.faces;
|
|
938
|
+
let i = 0;
|
|
939
|
+
while (i < faces.length) {
|
|
940
|
+
const n = faces[i]; // 面的顶点数量
|
|
941
|
+
mergedFaces[faceOffset++] = n;
|
|
942
|
+
for (let j = 1; j <= n; j++) {
|
|
943
|
+
mergedFaces[faceOffset++] = faces[i + j] + indexOffset;
|
|
944
|
+
}
|
|
945
|
+
i += n + 1;
|
|
946
|
+
}
|
|
1077
947
|
|
|
948
|
+
pointOffset += mesh.vertices.length;
|
|
949
|
+
indexOffset += mesh.vertices.length / 3; // 每个顶点占 3 个数
|
|
950
|
+
}
|
|
1078
951
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
*/
|
|
1084
|
-
export function mergePolyData(params) {
|
|
1085
|
-
const appendPolyData = vtkAppendPolyData.newInstance();
|
|
1086
|
-
params.forEach(data => {
|
|
1087
|
-
appendPolyData.addInputData(data);
|
|
1088
|
-
});
|
|
1089
|
-
return appendPolyData.getOutputData();
|
|
952
|
+
return {
|
|
953
|
+
vertices: mergedPoints,
|
|
954
|
+
faces: mergedFaces,
|
|
955
|
+
};
|
|
1090
956
|
}
|
|
1091
957
|
|
|
1092
958
|
/**
|
|
1093
959
|
* 计算网格的boundingBox
|
|
1094
|
-
* @param {
|
|
960
|
+
* @param { number[] | Float32Array } vertices 点数据
|
|
1095
961
|
* @returns 返回网格的boundingBox
|
|
1096
962
|
*/
|
|
1097
|
-
export function computeBoundingBox(
|
|
963
|
+
export function computeBoundingBox(vertices) {
|
|
1098
964
|
// 初始化最小值和最大值
|
|
1099
965
|
const min = vec3.fromValues(Infinity, Infinity, Infinity);
|
|
1100
966
|
const max = vec3.fromValues(-Infinity, -Infinity, -Infinity);
|
|
1101
967
|
|
|
1102
968
|
// 从 vtkPolyData 中提取顶点数据(假设是 Float32Array 格式)
|
|
1103
|
-
const points =
|
|
969
|
+
const points = vertices;
|
|
1104
970
|
const numPoints = points.length / 3;
|
|
1105
971
|
|
|
1106
972
|
// 遍历所有顶点
|
|
@@ -1124,11 +990,11 @@ export function computeBoundingBox(polydata) {
|
|
|
1124
990
|
|
|
1125
991
|
/**
|
|
1126
992
|
* 计算网格移动到相对自己中心位置的xyz偏移量
|
|
1127
|
-
* @param {
|
|
993
|
+
* @param { number[] | Float32Array } vertices 点数据
|
|
1128
994
|
* @returns {{x: number, y: number, z: number}} 网格自己居中所需要的xyz偏移量
|
|
1129
995
|
*/
|
|
1130
|
-
export function getPolydataCenterOffset(
|
|
1131
|
-
const _boundBox = computeBoundingBox(
|
|
996
|
+
export function getPolydataCenterOffset(vertices) {
|
|
997
|
+
const _boundBox = computeBoundingBox(vertices);
|
|
1132
998
|
const _width = Math.abs(_boundBox.min[0] - _boundBox.max[0]);
|
|
1133
999
|
const _height = Math.abs(_boundBox.min[1] - _boundBox.max[1]);
|
|
1134
1000
|
const _surface =Math.abs(_boundBox.min[2] - _boundBox.max[2]);
|
package/types/drcUtils.d.ts
CHANGED
|
@@ -68,12 +68,12 @@ export function enCloudPointTobase64(points: vec3[] | number[]): string;
|
|
|
68
68
|
*/
|
|
69
69
|
/**
|
|
70
70
|
* 使用drc压缩网格信息
|
|
71
|
-
* @param {Mesh
|
|
71
|
+
* @param {Mesh} mesh
|
|
72
72
|
* @param {number} byteLength=14 压缩率
|
|
73
73
|
* @param {AttrOption} [attr] 其他需要压缩的属性
|
|
74
74
|
* @returns {Int8Array} 压缩之后的DRC数据
|
|
75
75
|
*/
|
|
76
|
-
export function enCodeMesh(mesh: Mesh
|
|
76
|
+
export function enCodeMesh(mesh: Mesh, byteLength?: number, attr?: AttrOption): Int8Array;
|
|
77
77
|
/**
|
|
78
78
|
* 初始化Draco文件
|
|
79
79
|
*/
|
|
@@ -125,5 +125,4 @@ export type Mesh = {
|
|
|
125
125
|
*/
|
|
126
126
|
faces: number[][] | vec3[];
|
|
127
127
|
};
|
|
128
|
-
import { vec3 } from "gl-matrix";
|
|
129
|
-
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
|
|
128
|
+
import { vec3 } from "gl-matrix";
|
package/types/exportPLY.d.ts
CHANGED
|
@@ -12,5 +12,4 @@
|
|
|
12
12
|
* @param {boolean} withColors=true 面使用点索引
|
|
13
13
|
* @returns {string | DataView} 返回文件内容
|
|
14
14
|
*/
|
|
15
|
-
export function writePLY(polyData:
|
|
16
|
-
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
|
|
15
|
+
export function writePLY(polyData: any, format: "ascii" | "binary", dataByteOrder?: 0 | 1, headerComments?: string[], textureFileName?: string, textureCoordinatesName?: ["u", "v"], withNormals?: boolean, withUVs?: boolean, withColors?: boolean, withIndices?: boolean): string | DataView;
|
package/types/exportSTL.d.ts
CHANGED
|
@@ -9,11 +9,10 @@ export function dispersedPoints2Stl(points: number[]): void;
|
|
|
9
9
|
* @param {boolean} colorMagic=false 颜色
|
|
10
10
|
* @returns {Blob} 网格的BinarySTL文件内容
|
|
11
11
|
*/
|
|
12
|
-
export function exportBinarySTL(polydata:
|
|
12
|
+
export function exportBinarySTL(polydata: any, colorMagic?: boolean): Blob;
|
|
13
13
|
/**
|
|
14
14
|
* 获取网格的AsciiSTL文件类容
|
|
15
15
|
* @param {vtkPolyData} polydata 网格
|
|
16
16
|
* @returns {string} 网格的asciiSTL文件内容
|
|
17
17
|
*/
|
|
18
|
-
export function exportAsciiSTL(polydata:
|
|
19
|
-
import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData.js';
|
|
18
|
+
export function exportAsciiSTL(polydata: any): string;
|
package/types/vtkUtils.d.ts
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 计算屏幕坐标到三维坐标
|
|
3
|
-
* @param {vtkRenderer} renderer vtkRenderer
|
|
4
|
-
* @param {number} x display x position
|
|
5
|
-
* @param {number} y display y position
|
|
6
|
-
* @param {number} z display z position
|
|
7
|
-
* @returns {[number, number, number]} 三维坐标
|
|
8
|
-
*/
|
|
9
|
-
export function computeDisplayToWorld(renderer: vtkRenderer, x: number, y: number, z: number): [number, number, number];
|
|
10
|
-
/**
|
|
11
|
-
* 计算三维坐标到屏幕坐标
|
|
12
|
-
* @param {vtkRenderer} renderer vtkRenderer
|
|
13
|
-
* @param {number} x 三维坐标 x值
|
|
14
|
-
* @param {number} y 三维坐标 y值
|
|
15
|
-
* @param {number} z 三维坐标 z值
|
|
16
|
-
* @returns {[number, number, number]} 屏幕坐标
|
|
17
|
-
*/
|
|
18
|
-
export function computeWorldToDisplay(renderer: vtkRenderer, x: number, y: number, z: number): [number, number, number];
|
|
19
1
|
/**
|
|
20
2
|
* 计算 w2l(word 2 local, word to local) 的变换矩阵
|
|
21
3
|
* @param {vec3} center 中心点
|
|
@@ -34,24 +16,6 @@ export function getW2LMatrix(center: vec3, xaxis: vec3, yaxis: vec3, zaxis: vec3
|
|
|
34
16
|
* @returns { mat4 } 变换矩阵
|
|
35
17
|
*/
|
|
36
18
|
export function getL2WMatrix(center: vec3, xaxis: vec3, yaxis: vec3, zaxis: vec3): mat4;
|
|
37
|
-
/**
|
|
38
|
-
* 返回交互的interactorStyle
|
|
39
|
-
* @returns {vtkInteractorStyleManipulator} 交互的interactorStyle
|
|
40
|
-
*/
|
|
41
|
-
export function make3DInteractorStyle(): vtkInteractorStyleManipulator;
|
|
42
|
-
/**
|
|
43
|
-
* 移除并返回当前renderWindow的所有鼠标交互设定
|
|
44
|
-
* @param {vtkRenderWindowInteractor} interactor vtkRenderWindowInteractor
|
|
45
|
-
* @returns {any[]} 当前鼠标的所有交互Manipulators
|
|
46
|
-
*/
|
|
47
|
-
export function removeMouseInteraction(interactor: vtkRenderWindowInteractor): any[];
|
|
48
|
-
/**
|
|
49
|
-
* 给当前窗口设置交互Maintainers
|
|
50
|
-
* @param {vtkRenderWindowInteractor} interactor vtkRenderWindowInteractor
|
|
51
|
-
* @param {any[]} mm 所有的交互Maintainers
|
|
52
|
-
* @returns {void}
|
|
53
|
-
*/
|
|
54
|
-
export function resetAllMouseMaintainers(interactor: vtkRenderWindowInteractor, mm: any[]): void;
|
|
55
19
|
/**
|
|
56
20
|
* 将点投影到平面上
|
|
57
21
|
* @param {vec3} point 需要投影的点
|
|
@@ -121,12 +85,6 @@ export function getPointToLineDist(point: vec3, begin: vec3, end: vec3): number;
|
|
|
121
85
|
* @returns {number}
|
|
122
86
|
*/
|
|
123
87
|
export function getPointToPlaneDist(point: vec3, origin: vec3, normal: vec3): number;
|
|
124
|
-
/**
|
|
125
|
-
* 对一个polydata应用矩阵变化,直接改变点位置
|
|
126
|
-
* @param {mat4} mt4 变换矩阵
|
|
127
|
-
* @param {vtkPolyData} data 需要应用变换的polydata
|
|
128
|
-
*/
|
|
129
|
-
export function pointsApplyMat4(mt4: mat4, data: vtkPolyData): void;
|
|
130
88
|
/**
|
|
131
89
|
* 将点应用矩阵变换
|
|
132
90
|
* @param {vec3} point 三维点
|
|
@@ -147,13 +105,13 @@ export function vecTransfromByMat4(vec: vec3, matrix: mat4): vec3;
|
|
|
147
105
|
* @param {'ascii' | 'binary'} [format='ascii'] format 导出文件格式
|
|
148
106
|
* @returns {Blob} 网格的ply文件Blob
|
|
149
107
|
*/
|
|
150
|
-
export function createPlyBlob(mesh:
|
|
108
|
+
export function createPlyBlob(mesh: any, format?: "ascii" | "binary"): Blob;
|
|
151
109
|
/**
|
|
152
110
|
* 获取mesh的stl文件Blob,由于STL文件过大,只使用Binary格式
|
|
153
111
|
* @param {vtkPolyData} mesh 网格polydata
|
|
154
112
|
* @returns {Blob} 网格的BinarySTL文件Blob
|
|
155
113
|
*/
|
|
156
|
-
export function createStlBlob(mesh:
|
|
114
|
+
export function createStlBlob(mesh: any): Blob;
|
|
157
115
|
/**
|
|
158
116
|
* @typedef {Object} Mesh
|
|
159
117
|
* @property {number[][] | vec3[]} vertices 点信息
|
|
@@ -165,20 +123,14 @@ export function createStlBlob(mesh: vtkPolyData): Blob;
|
|
|
165
123
|
* @param {number} byteLength=14 压缩率
|
|
166
124
|
* @returns {Blob} drc文件
|
|
167
125
|
*/
|
|
168
|
-
export function createDrcBlob(mesh:
|
|
126
|
+
export function createDrcBlob(mesh: Mesh, byteLength?: number): Blob;
|
|
169
127
|
/**
|
|
170
128
|
* 将网格输出为对应类型的Blob,均采用默认参数,导出drc需要先加载draco_encode.js,并调用initDrcCoder初始化
|
|
171
129
|
* @param {vtkPolyData} mesh 网格文件
|
|
172
130
|
* @param {'ply' | 'stl' | 'drc' } type 输出类型
|
|
173
131
|
* @returns {Blob} 对应类型的Blob
|
|
174
132
|
*/
|
|
175
|
-
export function createMeshTypeBlob(mesh:
|
|
176
|
-
/**
|
|
177
|
-
* vtkPolyData的顶点去重 用于3倍顶点的stl和老版本的vtkMarchingCube
|
|
178
|
-
* @param {vtkPolyData} data 网格的vtkPolyData
|
|
179
|
-
* @returns {vtkPolyData} 去重之后的vtkPolyData
|
|
180
|
-
*/
|
|
181
|
-
export function deduplicatePolyData(data: vtkPolyData): vtkPolyData;
|
|
133
|
+
export function createMeshTypeBlob(mesh: any, type: "ply" | "stl" | "drc"): Blob;
|
|
182
134
|
/**
|
|
183
135
|
* 计算一组三维点的中心点
|
|
184
136
|
* @param {vec3[]} points 三维点数组
|
|
@@ -247,7 +199,7 @@ export function convEular2matrixZYX(rmat: mat3, xangle: number, yangle: number,
|
|
|
247
199
|
* @param {number} byteLength=14 压缩率
|
|
248
200
|
* @returns {string} drc压缩之后的网格base64
|
|
249
201
|
*/
|
|
250
|
-
export function enCodeMeshToBase64(mesh:
|
|
202
|
+
export function enCodeMeshToBase64(mesh: any | Mesh, matrix?: mat4, byteLength?: number): string;
|
|
251
203
|
/**
|
|
252
204
|
* 将一圈有序点按指定size进行平滑
|
|
253
205
|
* @param {vec3[]} points 一圈有序点
|
|
@@ -281,20 +233,6 @@ export function getAxisFormMat4(matrix: mat4): AxisObject;
|
|
|
281
233
|
* @returns {boolean} 是否是正交矩阵
|
|
282
234
|
*/
|
|
283
235
|
export function isRotationMatrix(matrix: mat4): boolean;
|
|
284
|
-
/**
|
|
285
|
-
* 将vtkPolyData进行三角化
|
|
286
|
-
* @param {vtkPolyData} polydata 需要三角化的vtkPolydata
|
|
287
|
-
* @returns {vtkPolyData} 三角化之后的vtkPolydata
|
|
288
|
-
*/
|
|
289
|
-
export function trianglePolys(polydata: vtkPolyData): vtkPolyData;
|
|
290
|
-
/**
|
|
291
|
-
* 加载网格
|
|
292
|
-
* @param {string | File | Blob} file 文件或者文件链接
|
|
293
|
-
* @param {'drc' | 'stl' | 'ply'} [type] 文件类型,当file为string | File的时候可以不传根据文件后缀自动获取,drc需要先进行初始化
|
|
294
|
-
* @param {boolean} [process] 是否需要预先对数据进行处理,stl默认(去重)
|
|
295
|
-
* @returns {Promise<vtkPolyData>} vtkPolyData
|
|
296
|
-
*/
|
|
297
|
-
export function loadMeshData(file: string | File | Blob, type?: "drc" | "stl" | "ply", process?: boolean): Promise<vtkPolyData>;
|
|
298
236
|
/**
|
|
299
237
|
* @typedef Plane
|
|
300
238
|
* @property {vec3} origin 对应vtk坐标系的x值
|
|
@@ -389,9 +327,6 @@ export type Plane = {
|
|
|
389
327
|
*/
|
|
390
328
|
normal: vec3;
|
|
391
329
|
};
|
|
392
|
-
import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer.js";
|
|
393
330
|
import { vec3 } from 'gl-matrix';
|
|
394
331
|
import { mat4 } from 'gl-matrix';
|
|
395
|
-
import vtkRenderWindowInteractor from "@kitware/vtk.js/Rendering/Core/RenderWindowInteractor.js";
|
|
396
|
-
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
|
|
397
332
|
import { mat3 } from 'gl-matrix';
|