xl-public-utils 1.0.14 → 1.0.15

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 CHANGED
@@ -682,6 +682,32 @@ declare module "xl-public-utils" {
682
682
  */
683
683
  export function initDrcCoder(): void;
684
684
  }
685
+ export namespace meshUtils {
686
+ /**
687
+ * * 生成一个六边形网格 polyData
688
+ * @param { number } rows 行数
689
+ * @param { number } cols 列数
690
+ * @param { number } radius 半径
691
+ * @param { number } wall 壁厚
692
+ * @param { number } height 高度
693
+ * @param { vec3 } center 中心位置
694
+ * @param { vec3 } axisX 朝向 X 轴,默认 [1, 0, 0]
695
+ * @param { vec3 } axisY 朝向 Y 轴,默认 [0, 1, 0]
696
+ * @param { vec3 } axisZ 朝向 Z 轴,默认 [0, 0, 1]
697
+ * @returns { vtkPolyData } polydata 六边形网格
698
+ */
699
+ export function createHexagonPolydata(
700
+ rows:number,
701
+ cols: number,
702
+ radius: number,
703
+ wall: number,
704
+ height: number,
705
+ center: vec3 = [0, 0, 0],
706
+ axisX: vec3 = [1, 0, 0],
707
+ axisY: vec3 = [0, 1, 0],
708
+ axisZ: vec3 = [0, 0, 1]
709
+ ): vtkPolyData
710
+ }
685
711
 
686
712
  export namespace utils {
687
713
  /**
package/index.js CHANGED
@@ -3,5 +3,6 @@ import * as utils from './src/utils.js'
3
3
  import * as qrcode from './src/qrcode.js'
4
4
  import * as BwipJs from './src/bwip-js.js';
5
5
  import * as drcUtils from './src/drcUtils.js';
6
+ import * as meshUtils from './src/meshUtils.js';
6
7
  import FontManager from './src/threeFont/index.js';
7
- export { vtkUtils, utils, qrcode, BwipJs, drcUtils, FontManager };
8
+ export { vtkUtils, utils, qrcode, BwipJs, drcUtils, FontManager, meshUtils };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xl-public-utils",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -0,0 +1,110 @@
1
+ import { ExtrudeGeometry } from './threeFont/TextGeometry/ExtrudeGeometry.js';
2
+ import { Shape } from './threeFont/Curve/Shape.js';
3
+ import { vec3, mat4 } from 'gl-matrix';
4
+ import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData.js';
5
+ import { clonePolyData, createPolyData, getL2WMatrix, getPolydataCenterOffset, mergePolyData, pointsApplyMat4 } from './vtkUtils.js';
6
+
7
+
8
+ /**
9
+ * * 生成六边形 Geometry
10
+ */
11
+ export function createHexagonGeometry(radius, height, wallThickness) {
12
+ // 创建外六边形
13
+ const outerShape = new Shape();
14
+ for (let i = 0; i < 6; i++) {
15
+ const angle = (i / 6) * Math.PI * 2;
16
+ const x = Math.cos(angle) * radius;
17
+ const y = Math.sin(angle) * radius;
18
+ if (i === 0) {
19
+ outerShape.moveTo(x, y);
20
+ } else {
21
+ outerShape.lineTo(x, y);
22
+ }
23
+ }
24
+
25
+ // 计算正确的内半径(关键修正)
26
+ const innerRadius = radius - wallThickness / Math.cos(Math.PI / 6); // 壁厚在半径方向的分量
27
+
28
+ if (innerRadius > 0) {
29
+ const innerShape = new Shape();
30
+ for (let i = 0; i < 6; i++) {
31
+ const angle = (i / 6) * Math.PI * 2;
32
+ const x = Math.cos(angle) * innerRadius;
33
+ const y = Math.sin(angle) * innerRadius;
34
+ if (i === 0) {
35
+ innerShape.moveTo(x, y);
36
+ } else {
37
+ innerShape.lineTo(x, y);
38
+ }
39
+ }
40
+ outerShape.holes.push(innerShape);
41
+ }
42
+
43
+ // 挤出几何体
44
+ const extrudeSettings = {
45
+ depth: height,
46
+ bevelEnabled: false
47
+ };
48
+
49
+ return new ExtrudeGeometry(outerShape, extrudeSettings);
50
+ }
51
+
52
+ /**
53
+ * * 生成一个六边形网格 polyData
54
+ * @param { number } rows 行数
55
+ * @param { number } cols 列数
56
+ * @param { number } radius 半径
57
+ * @param { number } wall 壁厚
58
+ * @param { number } height 高度
59
+ * @param { vec3 } center 中心位置
60
+ * @param { vec3 } axisX 朝向 X 轴,默认 [1, 0, 0]
61
+ * @param { vec3 } axisY 朝向 Y 轴,默认 [0, 1, 0]
62
+ * @param { vec3 } axisZ 朝向 Z 轴,默认 [0, 0, 1]
63
+ * @returns { vtkPolyData } polydata 六边形网格
64
+ */
65
+ export function createHexagonPolydata(
66
+ rows,
67
+ cols,
68
+ radius,
69
+ wall,
70
+ height,
71
+ center = [0, 0, 0],
72
+ axisX = [1, 0, 0],
73
+ axisY = [0, 1, 0],
74
+ axisZ = [0, 0, 1]
75
+ ) {
76
+ // 计算偏移量(根据OpenSCAD代码和形状调整)
77
+ const z = Math.sqrt(3); // sqrt(3);
78
+ const _wall = wall / Math.sqrt(2); //六边形网格边上有重叠
79
+
80
+ const a = radius * 1.5 - _wall / 2 / z;
81
+ const b = (radius / 2) * z - _wall / 2 / z;
82
+
83
+ const geometry = createHexagonGeometry(radius, height, _wall);
84
+ const polyData = createPolyData(geometry.vertices, geometry.faces);
85
+
86
+ let polyDataArr = [];
87
+ // 生成网格
88
+ for (let i = 0; i < rows; i++) {
89
+ let q = i % 2; // 奇偶行偏移
90
+ for (let j = 1; j <= cols; j++) {
91
+ let _polyData = clonePolyData(polyData);
92
+
93
+ // 根据形状和OpenSCAD公式计算位置
94
+ let x = i * a;
95
+ let y = j * b * 2 + q * b - b;
96
+ let _trans = mat4.fromTranslation(mat4.create(), [x, y, 0]);
97
+ pointsApplyMat4(_trans, _polyData);
98
+ polyDataArr.push(_polyData);
99
+ }
100
+ }
101
+
102
+ const resultPolyData = mergePolyData(polyDataArr);
103
+ const _offset = getPolydataCenterOffset(resultPolyData);
104
+ const offsetM4 = mat4.translate(mat4.create(), mat4.create(), [_offset.x, _offset.y, 0]);
105
+ pointsApplyMat4(offsetM4, resultPolyData);
106
+
107
+ const _matrix = getL2WMatrix(center, axisX, axisY, axisZ);
108
+ pointsApplyMat4(_matrix, resultPolyData);
109
+ return resultPolyData;
110
+ }
package/src/vtkUtils.js CHANGED
@@ -10,6 +10,9 @@ import vtkPLYReader from '@kitware/vtk.js/IO/Geometry/PLYReader';
10
10
  import vtkSTLReader from '@kitware/vtk.js/IO/Geometry/STLReader';
11
11
  import vtkDracoReader from '@kitware/vtk.js/IO/Geometry/DracoReader';
12
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';
13
16
  import { vec3, mat4, mat3, quat } from 'gl-matrix';
14
17
  import { exportBinarySTL } from './exportSTL.js';
15
18
  import { writePLY } from "./exportPLY.js";
@@ -1043,4 +1046,95 @@ export function clonePolyData(originalPolyData) {
1043
1046
  const originalCells = originalPolyData.getPolys().getData();
1044
1047
  clonedPolyData.getPolys().setData([...originalCells]);
1045
1048
  return clonedPolyData;
1049
+ }
1050
+
1051
+ /**
1052
+ * 根据点和面创建一个vtkPolydata
1053
+ * @param {number[] | TypedArray} verts
1054
+ * @param {number[] | TypedArray} faces
1055
+ * @returns { vtkPolyData } 生成出来的vtkPolydata
1056
+ */
1057
+ export function createPolyData(verts, faces) {
1058
+ let values_v = Object.values(verts);
1059
+ let values_f = Object.values(faces);
1060
+ let _verts = [];
1061
+ let _faces = [];
1062
+ values_v.forEach((v) => _verts.push(parseFloat(v)));
1063
+ values_f.forEach((f) => _faces.push(parseInt(f)));
1064
+
1065
+ const vpoints = vtkPoints.newInstance();
1066
+ const cellArray = vtkCellArray.newInstance();
1067
+
1068
+ vpoints.setData(_verts, 3);
1069
+ cellArray.setNumberOfComponents(4);
1070
+ cellArray.setData(_faces);
1071
+
1072
+ const polyData = vtkPolyData.newInstance();
1073
+ polyData.setPoints(vpoints);
1074
+ polyData.setPolys(cellArray);
1075
+ return polyData;
1076
+ }
1077
+
1078
+
1079
+ /**
1080
+ * 合并多个polydata
1081
+ * @param {vtkPolyData[]} params 多个polyData
1082
+ * @returns { vtkPolyData } 合并之后的polydata
1083
+ */
1084
+ export function mergePolyData(params) {
1085
+ const appendPolyData = vtkAppendPolyData.newInstance();
1086
+ params.forEach(data => {
1087
+ appendPolyData.addInputData(data);
1088
+ });
1089
+ return appendPolyData.getOutputData();
1090
+ }
1091
+
1092
+ /**
1093
+ * 计算网格的boundingBox
1094
+ * @param { vtkPolyData } polydata 网格数据
1095
+ * @returns 返回网格的boundingBox
1096
+ */
1097
+ export function computeBoundingBox(polydata) {
1098
+ // 初始化最小值和最大值
1099
+ const min = vec3.fromValues(Infinity, Infinity, Infinity);
1100
+ const max = vec3.fromValues(-Infinity, -Infinity, -Infinity);
1101
+
1102
+ // 从 vtkPolyData 中提取顶点数据(假设是 Float32Array 格式)
1103
+ const points = polydata.getPoints().getData();
1104
+ const numPoints = points.length / 3;
1105
+
1106
+ // 遍历所有顶点
1107
+ for (let i = 0; i < numPoints; i++) {
1108
+ const x = points[i * 3];
1109
+ const y = points[i * 3 + 1];
1110
+ const z = points[i * 3 + 2];
1111
+
1112
+ // 更新最小值和最大值
1113
+ min[0] = Math.min(min[0], x);
1114
+ min[1] = Math.min(min[1], y);
1115
+ min[2] = Math.min(min[2], z);
1116
+
1117
+ max[0] = Math.max(max[0], x);
1118
+ max[1] = Math.max(max[1], y);
1119
+ max[2] = Math.max(max[2], z);
1120
+ }
1121
+
1122
+ return { min, max };
1123
+ }
1124
+
1125
+ /**
1126
+ * 计算网格移动到相对自己中心位置的xyz偏移量
1127
+ * @param { vtkPolyData } _polydata 网格
1128
+ * @returns {{x: number, y: number, z: number}} 网格自己居中所需要的xyz偏移量
1129
+ */
1130
+ export function getPolydataCenterOffset(_polydata) {
1131
+ const _boundBox = computeBoundingBox(_polydata);
1132
+ const _width = Math.abs(_boundBox.min[0] - _boundBox.max[0]);
1133
+ const _height = Math.abs(_boundBox.min[1] - _boundBox.max[1]);
1134
+ const _surface =Math.abs(_boundBox.min[2] - _boundBox.max[2]);
1135
+ return {
1136
+ x: -(_boundBox.max[0] - _width / 2),
1137
+ y: -(_boundBox.max[1] - _height / 2),
1138
+ z: -(_boundBox.max[2] - _surface / 2),
1139
+ };
1046
1140
  }