brepjs 18.35.3 → 18.35.5
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/dist/2d.cjs +6 -6
- package/dist/2d.js +6 -6
- package/dist/{blueprint-BugZrlJZ.js → blueprint-DFX9Mice.js} +5 -5
- package/dist/{blueprint-BZtQ37hZ.cjs → blueprint-Dt8UBapg.cjs} +5 -5
- package/dist/{blueprintFns-DZreBQDw.js → blueprintFns-DKm_TMpq.js} +2 -2
- package/dist/{blueprintFns-Cd6RX-3U.cjs → blueprintFns-DUrh_Vuo.cjs} +2 -2
- package/dist/{blueprintSketcher-CeUtlreY.cjs → blueprintSketcher-CSWQy4s0.cjs} +3 -3
- package/dist/{blueprintSketcher-Br9S5j8n.js → blueprintSketcher-CqdAW9fb.js} +3 -3
- package/dist/{boolean2D-jMwDLuLK.js → boolean2D-CAMPcmle.js} +4 -4
- package/dist/{boolean2D-B30MyM5A.cjs → boolean2D-LKA2WvT1.cjs} +4 -4
- package/dist/{booleanFns-NkgP7bZA.cjs → booleanFns-BherB6vd.cjs} +4 -4
- package/dist/{booleanFns-BPWMgD1t.js → booleanFns-ky-zHUHR.js} +4 -4
- package/dist/brepjs.cjs +25 -25
- package/dist/brepjs.js +25 -25
- package/dist/{cameraFns-B5FrSRRP.js → cameraFns-AIlIbZXo.js} +2 -2
- package/dist/{cameraFns-Bb5fmsNi.cjs → cameraFns-D_6uvLNa.cjs} +2 -2
- package/dist/core.cjs +1 -1
- package/dist/core.js +1 -1
- package/dist/{cornerFinder-NT0nEY2D.js → cornerFinder-CHrWbA9J.js} +1 -1
- package/dist/{cornerFinder-Nd00yMHA.cjs → cornerFinder-D0D01Iv4.cjs} +1 -1
- package/dist/{curveFns-D1IaRpWu.js → curveFns-DC4gwhim.js} +1 -1
- package/dist/{curveFns-tBJhB6jA.cjs → curveFns-DplagD2s.cjs} +1 -1
- package/dist/{drawFns-BetA5msk.js → drawFns-2FS4bc0v.js} +12 -12
- package/dist/{drawFns-C9WFdiAW.cjs → drawFns-shtE96tg.cjs} +12 -12
- package/dist/{extrudeFns-DWeYb6cu.js → extrudeFns-B2koxf8d.js} +1 -1
- package/dist/{extrudeFns-Bg-IXT_O.cjs → extrudeFns-CGXjoiA3.cjs} +1 -1
- package/dist/{faceFns-ThsHosgU.cjs → faceFns-D-i7rp7Y.cjs} +2 -2
- package/dist/{faceFns-DBEEcVC-.js → faceFns-D9IXo1EY.js} +2 -2
- package/dist/{helpers-D2RrISk0.js → helpers-6tUnAb2m.js} +6 -6
- package/dist/{helpers-D6XMORWy.cjs → helpers-DoflJrR5.cjs} +6 -6
- package/dist/{historyFns-DrjICLPB.cjs → historyFns-1a841VzH.cjs} +4 -4
- package/dist/{historyFns-BSSA9qoA.js → historyFns-Y0v0weT9.js} +4 -4
- package/dist/{importFns-Cq-bKeDn.js → importFns-BsE_nugZ.js} +2 -2
- package/dist/{importFns-B7nffQNd.cjs → importFns-CzArHdFY.cjs} +2 -2
- package/dist/io.cjs +2 -2
- package/dist/io.js +2 -2
- package/dist/kernel/hullGeometry.d.ts +22 -0
- package/dist/kernel/occt/hullOps.d.ts +1 -6
- package/dist/kernel/occtWasm/hullOps.d.ts +1 -5
- package/dist/kernel/occtWasm/kernel2dOps.d.ts +7 -1
- package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
- package/dist/kernel/occtWasm/occtWasmAdapter.d.ts +1 -1
- package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
- package/dist/kernel/occtWasm/occtWasmTypes.d.ts +2 -0
- package/dist/{measureFns-BT_G8lXZ.cjs → measureFns-gkq2sYtY.cjs} +3 -3
- package/dist/{measureFns-BTn_t0LK.js → measureFns-ry6_O167.js} +3 -3
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-CR68GwS8.js → meshFns-CEECiqKQ.js} +3 -3
- package/dist/{meshFns-BcYvu4zj.cjs → meshFns-D-4VAld_.cjs} +3 -3
- package/dist/{occtWasmAdapter-DUruQhFF.js → occtWasmAdapter-DNXBos24.js} +360 -132
- package/dist/{occtWasmAdapter-R8zCS1h7.cjs → occtWasmAdapter-sH6wg1Z6.cjs} +365 -131
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +2 -2
- package/dist/{primitiveFns-BjeLfI12.js → primitiveFns-BiEXbXUy.js} +7 -7
- package/dist/{primitiveFns-DtY84t7q.cjs → primitiveFns-IFpwC8fs.cjs} +7 -7
- package/dist/projection.cjs +1 -1
- package/dist/projection.js +1 -1
- package/dist/query.cjs +2 -2
- package/dist/query.js +2 -2
- package/dist/{shapeFns-oS8Us7JQ.js → shapeFns-2ZBm7gZd.js} +2 -2
- package/dist/{shapeFns-lDEvCF5Q.cjs → shapeFns-BsNw-egb.cjs} +2 -2
- package/dist/shapeRef.cjs +1 -1
- package/dist/shapeRef.js +1 -1
- package/dist/{shapeRefFns-DHioZfFV.cjs → shapeRefFns-4I03ZCKU.cjs} +4 -4
- package/dist/{shapeRefFns-C2DbyKEO.js → shapeRefFns-VuIGZejB.js} +4 -4
- package/dist/{shapeTypes-BiX2PjaO.cjs → shapeTypes-CUTaIMCC.cjs} +5 -243
- package/dist/{shapeTypes-BH-9bXON.js → shapeTypes-CiEgOVu3.js} +3 -241
- package/dist/sketching.cjs +3 -3
- package/dist/sketching.js +3 -3
- package/dist/{solidBuilders-DR3oU7Fb.cjs → solidBuilders-0Y1U2uMs.cjs} +2 -2
- package/dist/{solidBuilders-BiduNSRx.js → solidBuilders-DV8lvLq3.js} +2 -2
- package/dist/{surfaceBuilders-xmm7fFbW.js → surfaceBuilders-DYzjeM-y.js} +2 -2
- package/dist/{surfaceBuilders-s2Uo2ard.cjs → surfaceBuilders-OUTnDgr5.cjs} +2 -2
- package/dist/text.cjs +2 -2
- package/dist/text.js +2 -2
- package/dist/{textBlueprints-DRh48_Fo.js → textBlueprints-00P4WdIq.js} +7 -7
- package/dist/{textBlueprints-Ca1NcWQg.cjs → textBlueprints-DQcSGfcQ.cjs} +7 -7
- package/dist/{textMetrics-BU6Ow8mb.js → textMetrics-8KJFgEn5.js} +1 -1
- package/dist/{textMetrics-CGN19mAp.cjs → textMetrics-Av8N82V_.cjs} +1 -1
- package/dist/topology.cjs +7 -7
- package/dist/topology.js +7 -7
- package/dist/{topologyQueryFns-B8uqQlEU.js → topologyQueryFns-DXKyoFvA.js} +1 -1
- package/dist/{topologyQueryFns-BoMkI1jZ.cjs → topologyQueryFns-j7sTNssl.cjs} +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,255 @@
|
|
|
1
1
|
import { n as wasmIndex } from "./vec3-Dpha8d5k.js";
|
|
2
|
+
//#region src/kernel/hullGeometry.ts
|
|
3
|
+
function sub(a, b) {
|
|
4
|
+
return {
|
|
5
|
+
x: a.x - b.x,
|
|
6
|
+
y: a.y - b.y,
|
|
7
|
+
z: a.z - b.z
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function cross(a, b) {
|
|
11
|
+
return {
|
|
12
|
+
x: a.y * b.z - a.z * b.y,
|
|
13
|
+
y: a.z * b.x - a.x * b.z,
|
|
14
|
+
z: a.x * b.y - a.y * b.x
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function dot(a, b) {
|
|
18
|
+
return a.x * b.x + a.y * b.y + a.z * b.z;
|
|
19
|
+
}
|
|
20
|
+
function lengthVec(v) {
|
|
21
|
+
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
|
22
|
+
}
|
|
23
|
+
function distSq(a, b) {
|
|
24
|
+
const dx = a.x - b.x;
|
|
25
|
+
const dy = a.y - b.y;
|
|
26
|
+
const dz = a.z - b.z;
|
|
27
|
+
return dx * dx + dy * dy + dz * dz;
|
|
28
|
+
}
|
|
29
|
+
/** Safe array access — throws on out-of-bounds instead of returning undefined. */
|
|
30
|
+
function at(arr, i) {
|
|
31
|
+
const v = arr[i];
|
|
32
|
+
if (v === void 0) throw new Error(`Index ${i} out of bounds`);
|
|
33
|
+
return v;
|
|
34
|
+
}
|
|
35
|
+
/** Safe number array access. */
|
|
36
|
+
function atN(arr, i) {
|
|
37
|
+
const v = arr[i];
|
|
38
|
+
if (v === void 0) throw new Error(`Index ${i} out of bounds`);
|
|
39
|
+
return v;
|
|
40
|
+
}
|
|
41
|
+
function makeFace$1(points, a, b, c) {
|
|
42
|
+
const normal = cross(sub(at(points, b), at(points, a)), sub(at(points, c), at(points, a)));
|
|
43
|
+
const len = lengthVec(normal);
|
|
44
|
+
const n = len > 1e-14 ? {
|
|
45
|
+
x: normal.x / len,
|
|
46
|
+
y: normal.y / len,
|
|
47
|
+
z: normal.z / len
|
|
48
|
+
} : normal;
|
|
49
|
+
return {
|
|
50
|
+
a,
|
|
51
|
+
b,
|
|
52
|
+
c,
|
|
53
|
+
normal: n,
|
|
54
|
+
offset: dot(n, at(points, a)),
|
|
55
|
+
alive: true,
|
|
56
|
+
outsidePoints: []
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function signedDist(face, point) {
|
|
60
|
+
return dot(face.normal, point) - face.offset;
|
|
61
|
+
}
|
|
62
|
+
function deduplicatePoints(points, tolerance) {
|
|
63
|
+
const tolSq = tolerance * tolerance;
|
|
64
|
+
const result = [];
|
|
65
|
+
for (const p of points) {
|
|
66
|
+
let isDuplicate = false;
|
|
67
|
+
for (const q of result) if (distSq(p, q) < tolSq) {
|
|
68
|
+
isDuplicate = true;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (!isDuplicate) result.push(p);
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
function findInitialTetrahedron(points) {
|
|
76
|
+
const n = points.length;
|
|
77
|
+
if (n < 4) return null;
|
|
78
|
+
let i0 = 0;
|
|
79
|
+
let i1 = 1;
|
|
80
|
+
let maxDist = distSq(at(points, 0), at(points, 1));
|
|
81
|
+
for (let i = 0; i < n; i++) for (let j = i + 1; j < n; j++) {
|
|
82
|
+
const d = distSq(at(points, i), at(points, j));
|
|
83
|
+
if (d > maxDist) {
|
|
84
|
+
maxDist = d;
|
|
85
|
+
i0 = i;
|
|
86
|
+
i1 = j;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (maxDist < 1e-20) return null;
|
|
90
|
+
const lineDir = sub(at(points, i1), at(points, i0));
|
|
91
|
+
let i2 = -1;
|
|
92
|
+
let maxLineDist = -1;
|
|
93
|
+
for (let i = 0; i < n; i++) {
|
|
94
|
+
if (i === i0 || i === i1) continue;
|
|
95
|
+
const c = cross(lineDir, sub(at(points, i), at(points, i0)));
|
|
96
|
+
const d = dot(c, c);
|
|
97
|
+
if (d > maxLineDist) {
|
|
98
|
+
maxLineDist = d;
|
|
99
|
+
i2 = i;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (i2 === -1 || maxLineDist < 1e-20) return null;
|
|
103
|
+
const planeNormal = cross(sub(at(points, i1), at(points, i0)), sub(at(points, i2), at(points, i0)));
|
|
104
|
+
const planeLen = lengthVec(planeNormal);
|
|
105
|
+
if (planeLen < 1e-14) return null;
|
|
106
|
+
const pn = {
|
|
107
|
+
x: planeNormal.x / planeLen,
|
|
108
|
+
y: planeNormal.y / planeLen,
|
|
109
|
+
z: planeNormal.z / planeLen
|
|
110
|
+
};
|
|
111
|
+
const planeOffset = dot(pn, at(points, i0));
|
|
112
|
+
let i3 = -1;
|
|
113
|
+
let maxPlaneDist = -1;
|
|
114
|
+
for (let i = 0; i < n; i++) {
|
|
115
|
+
if (i === i0 || i === i1 || i === i2) continue;
|
|
116
|
+
const d = Math.abs(dot(pn, at(points, i)) - planeOffset);
|
|
117
|
+
if (d > maxPlaneDist) {
|
|
118
|
+
maxPlaneDist = d;
|
|
119
|
+
i3 = i;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (i3 === -1 || maxPlaneDist < 1e-14) return null;
|
|
123
|
+
if (dot(pn, at(points, i3)) - planeOffset > 0) return [
|
|
124
|
+
i0,
|
|
125
|
+
i2,
|
|
126
|
+
i1,
|
|
127
|
+
i3
|
|
128
|
+
];
|
|
129
|
+
return [
|
|
130
|
+
i0,
|
|
131
|
+
i1,
|
|
132
|
+
i2,
|
|
133
|
+
i3
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Compute the 3D convex hull of a point set.
|
|
138
|
+
*
|
|
139
|
+
* @throws if fewer than 4 non-coincident, non-coplanar points are supplied.
|
|
140
|
+
*/
|
|
141
|
+
function quickHull(inputPoints, tolerance) {
|
|
142
|
+
const points = deduplicatePoints(inputPoints, tolerance);
|
|
143
|
+
if (points.length < 4) throw new Error(points.length === 0 ? "No points provided for convex hull" : "Fewer than 4 non-coincident points; cannot form a 3D convex hull");
|
|
144
|
+
const tet = findInitialTetrahedron(points);
|
|
145
|
+
if (tet === null) throw new Error("All points are coplanar; cannot form a 3D convex hull");
|
|
146
|
+
const [t0, t1, t2, t3] = tet;
|
|
147
|
+
const centroid = {
|
|
148
|
+
x: (at(points, t0).x + at(points, t1).x + at(points, t2).x + at(points, t3).x) / 4,
|
|
149
|
+
y: (at(points, t0).y + at(points, t1).y + at(points, t2).y + at(points, t3).y) / 4,
|
|
150
|
+
z: (at(points, t0).z + at(points, t1).z + at(points, t2).z + at(points, t3).z) / 4
|
|
151
|
+
};
|
|
152
|
+
function makeOutwardFace(a, b, c) {
|
|
153
|
+
const face = makeFace$1(points, a, b, c);
|
|
154
|
+
const toCentroid = sub(centroid, {
|
|
155
|
+
x: (at(points, a).x + at(points, b).x + at(points, c).x) / 3,
|
|
156
|
+
y: (at(points, a).y + at(points, b).y + at(points, c).y) / 3,
|
|
157
|
+
z: (at(points, a).z + at(points, b).z + at(points, c).z) / 3
|
|
158
|
+
});
|
|
159
|
+
if (dot(face.normal, toCentroid) > 0) return makeFace$1(points, a, c, b);
|
|
160
|
+
return face;
|
|
161
|
+
}
|
|
162
|
+
const faces = [
|
|
163
|
+
makeOutwardFace(t0, t1, t2),
|
|
164
|
+
makeOutwardFace(t0, t2, t3),
|
|
165
|
+
makeOutwardFace(t0, t3, t1),
|
|
166
|
+
makeOutwardFace(t1, t3, t2)
|
|
167
|
+
];
|
|
168
|
+
const tetSet = new Set([
|
|
169
|
+
t0,
|
|
170
|
+
t1,
|
|
171
|
+
t2,
|
|
172
|
+
t3
|
|
173
|
+
]);
|
|
174
|
+
const epsilon = 1e-10;
|
|
175
|
+
for (let i = 0; i < points.length; i++) {
|
|
176
|
+
if (tetSet.has(i)) continue;
|
|
177
|
+
for (const face of faces) if (signedDist(face, at(points, i)) > epsilon) {
|
|
178
|
+
face.outsidePoints.push(i);
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
for (let iteration = 0; iteration < points.length * 4; iteration++) {
|
|
183
|
+
let currentFace = null;
|
|
184
|
+
for (const face of faces) if (face.alive && face.outsidePoints.length > 0) {
|
|
185
|
+
currentFace = face;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
if (currentFace === null) break;
|
|
189
|
+
let furthestIdx = atN(currentFace.outsidePoints, 0);
|
|
190
|
+
let furthestDist = signedDist(currentFace, at(points, furthestIdx));
|
|
191
|
+
for (let i = 1; i < currentFace.outsidePoints.length; i++) {
|
|
192
|
+
const idx = atN(currentFace.outsidePoints, i);
|
|
193
|
+
const d = signedDist(currentFace, at(points, idx));
|
|
194
|
+
if (d > furthestDist) {
|
|
195
|
+
furthestDist = d;
|
|
196
|
+
furthestIdx = idx;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const visibleFaces = [];
|
|
200
|
+
for (const face of faces) if (face.alive && signedDist(face, at(points, furthestIdx)) > epsilon) visibleFaces.push(face);
|
|
201
|
+
const edgeCount = /* @__PURE__ */ new Map();
|
|
202
|
+
for (const face of visibleFaces) {
|
|
203
|
+
const edges = [
|
|
204
|
+
[face.a, face.b],
|
|
205
|
+
[face.b, face.c],
|
|
206
|
+
[face.c, face.a]
|
|
207
|
+
];
|
|
208
|
+
for (const [ea, eb] of edges) {
|
|
209
|
+
const key = ea < eb ? `${ea}-${eb}` : `${eb}-${ea}`;
|
|
210
|
+
const entry = edgeCount.get(key);
|
|
211
|
+
if (entry) entry.count++;
|
|
212
|
+
else edgeCount.set(key, {
|
|
213
|
+
a: ea,
|
|
214
|
+
b: eb,
|
|
215
|
+
count: 1
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const horizonEdges = [];
|
|
220
|
+
for (const entry of edgeCount.values()) if (entry.count === 1) horizonEdges.push({
|
|
221
|
+
a: entry.a,
|
|
222
|
+
b: entry.b
|
|
223
|
+
});
|
|
224
|
+
const orphanedPoints = [];
|
|
225
|
+
for (const face of visibleFaces) {
|
|
226
|
+
for (const idx of face.outsidePoints) if (idx !== furthestIdx) orphanedPoints.push(idx);
|
|
227
|
+
face.alive = false;
|
|
228
|
+
face.outsidePoints = [];
|
|
229
|
+
}
|
|
230
|
+
const newFaces = [];
|
|
231
|
+
for (const edge of horizonEdges) {
|
|
232
|
+
const newFaceObj = makeFace$1(points, edge.a, edge.b, furthestIdx);
|
|
233
|
+
newFaces.push(newFaceObj);
|
|
234
|
+
faces.push(newFaceObj);
|
|
235
|
+
}
|
|
236
|
+
for (const idx of orphanedPoints) for (const face of newFaces) if (signedDist(face, at(points, idx)) > epsilon) {
|
|
237
|
+
face.outsidePoints.push(idx);
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const resultFaces = [];
|
|
242
|
+
for (const face of faces) if (face.alive) resultFaces.push([
|
|
243
|
+
face.a,
|
|
244
|
+
face.b,
|
|
245
|
+
face.c
|
|
246
|
+
]);
|
|
247
|
+
return {
|
|
248
|
+
faces: resultFaces,
|
|
249
|
+
points
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
//#endregion
|
|
2
253
|
//#region src/kernel/geometry2d.ts
|
|
3
254
|
function evaluateCurve2d$1(c, t) {
|
|
4
255
|
switch (c.__bk2d) {
|
|
@@ -1115,6 +1366,12 @@ function mesh(k, Module, shape, options) {
|
|
|
1115
1366
|
for (let i = 0; i < posCount; i++) vertices[i] = Module.HEAPF32[posPtr + i] ?? 0;
|
|
1116
1367
|
const normals = new Float32Array(normCount);
|
|
1117
1368
|
if (!options.skipNormals) for (let i = 0; i < normCount; i++) normals[i] = Module.HEAPF32[normPtr + i] ?? 0;
|
|
1369
|
+
const uvCount = meshData.uvCount;
|
|
1370
|
+
const uvs = new Float32Array(options.includeUVs ? uvCount : 0);
|
|
1371
|
+
if (options.includeUVs && uvCount > 0) {
|
|
1372
|
+
const uvPtr = meshData.getUvsPtr() >> 2;
|
|
1373
|
+
for (let i = 0; i < uvCount; i++) uvs[i] = Module.HEAPF32[uvPtr + i] ?? 0;
|
|
1374
|
+
}
|
|
1118
1375
|
const triangles = new Uint32Array(idxCount);
|
|
1119
1376
|
for (let i = 0; i < idxCount; i++) triangles[i] = Module.HEAPU32[idxPtr + i] ?? 0;
|
|
1120
1377
|
const faceGroups = [];
|
|
@@ -1131,7 +1388,7 @@ function mesh(k, Module, shape, options) {
|
|
|
1131
1388
|
vertices,
|
|
1132
1389
|
normals: options.skipNormals ? new Float32Array(0) : normals,
|
|
1133
1390
|
triangles,
|
|
1134
|
-
uvs
|
|
1391
|
+
uvs,
|
|
1135
1392
|
faceGroups
|
|
1136
1393
|
};
|
|
1137
1394
|
} finally {
|
|
@@ -2974,10 +3231,27 @@ function makeEllipseArc2d(cx, cy, majorRadius, minorRadius, startAngle, endAngle
|
|
|
2974
3231
|
function makeBezier2d(points) {
|
|
2975
3232
|
return c2dWrap(makeBezier2d$1(points));
|
|
2976
3233
|
}
|
|
2977
|
-
function makeBSpline2d(points) {
|
|
2978
|
-
|
|
2979
|
-
const
|
|
2980
|
-
|
|
3234
|
+
function makeBSpline2d(points, options) {
|
|
3235
|
+
const poles = points;
|
|
3236
|
+
const n = poles.length;
|
|
3237
|
+
const degree = Math.max(1, Math.min(options?.degMax ?? 3, n - 1));
|
|
3238
|
+
const knots = [0];
|
|
3239
|
+
const mults = [degree + 1];
|
|
3240
|
+
const nInternalKnots = n - degree - 1;
|
|
3241
|
+
for (let i = 1; i <= nInternalKnots; i++) {
|
|
3242
|
+
knots.push(i / (nInternalKnots + 1));
|
|
3243
|
+
mults.push(1);
|
|
3244
|
+
}
|
|
3245
|
+
knots.push(1);
|
|
3246
|
+
mults.push(degree + 1);
|
|
3247
|
+
return c2dWrap({
|
|
3248
|
+
__bk2d: "bspline",
|
|
3249
|
+
poles,
|
|
3250
|
+
knots,
|
|
3251
|
+
multiplicities: mults,
|
|
3252
|
+
degree,
|
|
3253
|
+
isPeriodic: false
|
|
3254
|
+
});
|
|
2981
3255
|
}
|
|
2982
3256
|
function evaluateCurve2d(curve, param) {
|
|
2983
3257
|
return evaluateCurve2d$1(c2d(curve), param);
|
|
@@ -3222,16 +3496,53 @@ function approximateCurve2dAsBSpline(curve, maxSegments) {
|
|
|
3222
3496
|
});
|
|
3223
3497
|
}
|
|
3224
3498
|
function decomposeBSpline2dToBeziers(curve) {
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3499
|
+
let cu = c2d(curve);
|
|
3500
|
+
while (cu.__bk2d === "trimmed" && cu.basis) cu = cu.basis;
|
|
3501
|
+
if (cu.__bk2d !== "bspline") return [curve];
|
|
3502
|
+
const poles = cu.poles;
|
|
3503
|
+
const p = cu.degree;
|
|
3504
|
+
const U = [];
|
|
3505
|
+
for (let i = 0; i < cu.knots.length; i++) for (let j = 0; j < cu.multiplicities[i]; j++) U.push(cu.knots[i]);
|
|
3506
|
+
const m = poles.length - 1 + p + 1;
|
|
3507
|
+
if (p < 1 || U.length !== m + 1) return [c2dWrap(makeBezier2d$1(poles))];
|
|
3508
|
+
const clone = (pt) => [pt[0], pt[1]];
|
|
3509
|
+
const segments = [];
|
|
3510
|
+
let a = p;
|
|
3511
|
+
let b = p + 1;
|
|
3512
|
+
let segPoles = [];
|
|
3513
|
+
for (let i = 0; i <= p; i++) segPoles[i] = clone(poles[i]);
|
|
3514
|
+
let nextPoles = [];
|
|
3515
|
+
while (b < m) {
|
|
3516
|
+
const i0 = b;
|
|
3517
|
+
while (b < m && U[b + 1] === U[b]) b++;
|
|
3518
|
+
const mult = b - i0 + 1;
|
|
3519
|
+
if (mult < p) {
|
|
3520
|
+
const numer = U[b] - U[a];
|
|
3521
|
+
const alphas = [];
|
|
3522
|
+
for (let j = p; j > mult; j--) alphas[j - mult - 1] = numer / (U[a + j] - U[a]);
|
|
3523
|
+
const r = p - mult;
|
|
3524
|
+
for (let j = 1; j <= r; j++) {
|
|
3525
|
+
const save = r - j;
|
|
3526
|
+
const s = mult + j;
|
|
3527
|
+
for (let k = p; k >= s; k--) {
|
|
3528
|
+
const alpha = alphas[k - s];
|
|
3529
|
+
const cur = segPoles[k];
|
|
3530
|
+
const prev = segPoles[k - 1];
|
|
3531
|
+
segPoles[k] = [alpha * cur[0] + (1 - alpha) * prev[0], alpha * cur[1] + (1 - alpha) * prev[1]];
|
|
3532
|
+
}
|
|
3533
|
+
if (b < m) nextPoles[save] = clone(segPoles[p]);
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
segments.push(segPoles);
|
|
3537
|
+
if (b < m) {
|
|
3538
|
+
for (let i = p - mult; i <= p; i++) nextPoles[i] = clone(poles[b - p + i]);
|
|
3539
|
+
segPoles = nextPoles;
|
|
3540
|
+
nextPoles = [];
|
|
3541
|
+
a = b;
|
|
3542
|
+
b++;
|
|
3543
|
+
}
|
|
3233
3544
|
}
|
|
3234
|
-
return
|
|
3545
|
+
return segments.map((sp) => c2dWrap(makeBezier2d$1(sp)));
|
|
3235
3546
|
}
|
|
3236
3547
|
function createBoundingBox2d() {
|
|
3237
3548
|
return createBBox2d();
|
|
@@ -3684,124 +3995,41 @@ function applyComposedTransformWithHistory(transformFn, iterShapesFn, hashCodeFn
|
|
|
3684
3995
|
}
|
|
3685
3996
|
//#endregion
|
|
3686
3997
|
//#region src/kernel/occtWasm/hullOps.ts
|
|
3687
|
-
function
|
|
3688
|
-
|
|
3689
|
-
const
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
for (let ei = 0; ei < 3; ei++) {
|
|
3693
|
-
const a = f[ei], b = f[(ei + 1) % 3];
|
|
3694
|
-
if (faces.some((g, fj) => fj !== fi && !visSet.has(fj) && [
|
|
3695
|
-
0,
|
|
3696
|
-
1,
|
|
3697
|
-
2
|
|
3698
|
-
].some((ej) => g[ej] === b && g[(ej + 1) % 3] === a))) horizon.push([a, b]);
|
|
3699
|
-
}
|
|
3700
|
-
}
|
|
3701
|
-
return horizon;
|
|
3998
|
+
function hullFromPoints(k, Module, points, tolerance) {
|
|
3999
|
+
if (points.length < 4) throw new Error("hullFromPoints: need at least 4 points");
|
|
4000
|
+
const { points: hullPoints, faces } = quickHull(points, tolerance);
|
|
4001
|
+
if (faces.length < 4) throw new Error("hullFromPoints: degenerate hull (fewer than 4 faces)");
|
|
4002
|
+
return buildSolidFromFaces(k, Module, [...hullPoints], [...faces], tolerance);
|
|
3702
4003
|
}
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
const
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
}
|
|
3724
|
-
let i2 = i1 + 1;
|
|
3725
|
-
const e01 = sub(pts[i1], p0);
|
|
3726
|
-
while (i2 < n) {
|
|
3727
|
-
const c = cross(e01, sub(pts[i2], p0));
|
|
3728
|
-
if (Math.hypot(c.x, c.y, c.z) > 1e-10) break;
|
|
3729
|
-
i2++;
|
|
3730
|
-
}
|
|
3731
|
-
let i3 = i2 + 1;
|
|
3732
|
-
const norm = cross(e01, sub(pts[i2], p0));
|
|
3733
|
-
while (i3 < n) {
|
|
3734
|
-
if (Math.abs(dot(norm, sub(pts[i3], p0))) > 1e-10) break;
|
|
3735
|
-
i3++;
|
|
3736
|
-
}
|
|
3737
|
-
if (i3 >= n) return [[
|
|
3738
|
-
0,
|
|
3739
|
-
1,
|
|
3740
|
-
2
|
|
3741
|
-
]];
|
|
3742
|
-
if (dot(cross(sub(pts[i1], p0), sub(pts[i2], p0)), sub(pts[i3], p0)) > 0) faces.push([
|
|
3743
|
-
0,
|
|
3744
|
-
i1,
|
|
3745
|
-
i2
|
|
3746
|
-
], [
|
|
3747
|
-
0,
|
|
3748
|
-
i2,
|
|
3749
|
-
i3
|
|
3750
|
-
], [
|
|
3751
|
-
0,
|
|
3752
|
-
i3,
|
|
3753
|
-
i1
|
|
3754
|
-
], [
|
|
3755
|
-
i1,
|
|
3756
|
-
i3,
|
|
3757
|
-
i2
|
|
3758
|
-
]);
|
|
3759
|
-
else faces.push([
|
|
3760
|
-
0,
|
|
3761
|
-
i2,
|
|
3762
|
-
i1
|
|
3763
|
-
], [
|
|
3764
|
-
0,
|
|
3765
|
-
i3,
|
|
3766
|
-
i2
|
|
3767
|
-
], [
|
|
3768
|
-
0,
|
|
3769
|
-
i1,
|
|
3770
|
-
i3
|
|
3771
|
-
], [
|
|
3772
|
-
i2,
|
|
3773
|
-
i3,
|
|
3774
|
-
i1
|
|
3775
|
-
]);
|
|
3776
|
-
const used = new Set([
|
|
3777
|
-
0,
|
|
3778
|
-
i1,
|
|
3779
|
-
i2,
|
|
3780
|
-
i3
|
|
3781
|
-
]);
|
|
3782
|
-
for (let pi = 0; pi < n; pi++) {
|
|
3783
|
-
if (used.has(pi)) continue;
|
|
3784
|
-
const p = pts[pi];
|
|
3785
|
-
const visible = [];
|
|
3786
|
-
for (let fi = 0; fi < faces.length; fi++) {
|
|
3787
|
-
const f = faces[fi];
|
|
3788
|
-
if (dot(cross(sub(pts[f[1]], pts[f[0]]), sub(pts[f[2]], pts[f[0]])), sub(p, pts[f[0]])) > 1e-10) visible.push(fi);
|
|
4004
|
+
/**
|
|
4005
|
+
* Sample surface vertices of each shape via tessellation. A coarse deflection
|
|
4006
|
+
* keeps the point count low — the convex hull only needs extreme points, and
|
|
4007
|
+
* fine meshes on curved surfaces explode the hull cost.
|
|
4008
|
+
*/
|
|
4009
|
+
function extractVertices(k, Module, shapes, tolerance) {
|
|
4010
|
+
const deflection = Math.max(tolerance, 1);
|
|
4011
|
+
const points = [];
|
|
4012
|
+
for (const shape of shapes) {
|
|
4013
|
+
const meshData = k.tessellate(unwrap(shape), deflection, deflection * .5);
|
|
4014
|
+
try {
|
|
4015
|
+
const posCount = meshData.positionCount;
|
|
4016
|
+
const posPtr = meshData.getPositionsPtr() >> 2;
|
|
4017
|
+
for (let i = 0; i < posCount; i += 3) points.push({
|
|
4018
|
+
x: Module.HEAPF32[posPtr + i] ?? 0,
|
|
4019
|
+
y: Module.HEAPF32[posPtr + i + 1] ?? 0,
|
|
4020
|
+
z: Module.HEAPF32[posPtr + i + 2] ?? 0
|
|
4021
|
+
});
|
|
4022
|
+
} finally {
|
|
4023
|
+
meshData.delete();
|
|
3789
4024
|
}
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
visible.sort((a2, b2) => b2 - a2);
|
|
3793
|
-
for (const fi of visible) faces.splice(fi, 1);
|
|
3794
|
-
for (const [a, b] of horizon) faces.push([
|
|
3795
|
-
a,
|
|
3796
|
-
b,
|
|
3797
|
-
pi
|
|
3798
|
-
]);
|
|
3799
|
-
}
|
|
3800
|
-
return faces;
|
|
4025
|
+
}
|
|
4026
|
+
return points;
|
|
3801
4027
|
}
|
|
3802
|
-
function
|
|
3803
|
-
if (
|
|
3804
|
-
|
|
4028
|
+
function hull(k, Module, shapes, tolerance) {
|
|
4029
|
+
if (shapes.length === 0) throw new Error("hull: no shapes provided");
|
|
4030
|
+
const points = extractVertices(k, Module, shapes, tolerance);
|
|
4031
|
+
if (points.length < 4) throw new Error("hull: fewer than 4 vertices extracted from input shapes");
|
|
4032
|
+
return hullFromPoints(k, Module, points, tolerance);
|
|
3805
4033
|
}
|
|
3806
4034
|
//#endregion
|
|
3807
4035
|
//#region src/kernel/occtWasm/occtWasmAdapter.ts
|
|
@@ -3957,8 +4185,8 @@ var OcctWasmAdapter = class OcctWasmAdapter {
|
|
|
3957
4185
|
solidFromShell(shell) {
|
|
3958
4186
|
return solidFromShell(this.k, shell);
|
|
3959
4187
|
}
|
|
3960
|
-
hull(
|
|
3961
|
-
|
|
4188
|
+
hull(shapes, tolerance) {
|
|
4189
|
+
return hull(this.k, this.Module, shapes, tolerance);
|
|
3962
4190
|
}
|
|
3963
4191
|
hullFromPoints(points, tolerance) {
|
|
3964
4192
|
return hullFromPoints(this.k, this.Module, points, tolerance);
|
|
@@ -4620,4 +4848,4 @@ var OcctWasmAdapter = class OcctWasmAdapter {
|
|
|
4620
4848
|
}
|
|
4621
4849
|
};
|
|
4622
4850
|
//#endregion
|
|
4623
|
-
export { serializeCurve2d$1 as _, curveTypeName as a, intersectCurves2dFn as c, makeEllipse2d$1 as d, makeLine2d$1 as f, scaleCurve2d$1 as g, rotateCurve2d$1 as h, curveBounds as i, makeBezier2d$1 as l, mirrorAtPoint as m, addCurveToBBox as n, deserializeCurve2d$1 as o, mirrorAcrossAxis as p, createBBox2d as r, evaluateCurve2d$1 as s, OcctWasmAdapter as t, makeCircle2d$1 as u, tangentCurve2d as v, translateCurve2d$1 as y };
|
|
4851
|
+
export { serializeCurve2d$1 as _, curveTypeName as a, quickHull as b, intersectCurves2dFn as c, makeEllipse2d$1 as d, makeLine2d$1 as f, scaleCurve2d$1 as g, rotateCurve2d$1 as h, curveBounds as i, makeBezier2d$1 as l, mirrorAtPoint as m, addCurveToBBox as n, deserializeCurve2d$1 as o, mirrorAcrossAxis as p, createBBox2d as r, evaluateCurve2d$1 as s, OcctWasmAdapter as t, makeCircle2d$1 as u, tangentCurve2d as v, translateCurve2d$1 as y };
|