brepjs 13.0.0 → 13.2.0
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 +3 -3
- package/dist/2d.js +3 -3
- package/dist/{arrayAccess-CccV7jov.js → arrayAccess-Dps31ERU.js} +3 -3
- package/dist/{arrayAccess-BF8Hm4-H.cjs → arrayAccess-peFKE9Ob.cjs} +3 -3
- package/dist/{blueprint-mSGgCL3V.js → blueprint-DYCdRlW5.js} +8 -8
- package/dist/{blueprint-BP3P8Ado.cjs → blueprint-PLJan-W5.cjs} +8 -8
- package/dist/{blueprintFns-BQ-MP_Vy.cjs → blueprintFns-Bsx25BG7.cjs} +3 -3
- package/dist/{blueprintFns-DWFkjbDT.js → blueprintFns-eWh7NpZx.js} +3 -3
- package/dist/{boolean2D-Cqfwz60G.js → boolean2D-52qVCooY.js} +10 -10
- package/dist/{boolean2D-D76Hc7Wx.cjs → boolean2D-CtB21ajK.cjs} +10 -10
- package/dist/{booleanFns-CYPXeNVN.cjs → booleanFns-BrptUFkP.cjs} +25 -13
- package/dist/{booleanFns-B79ALtKn.js → booleanFns-iM6UPb8e.js} +25 -13
- package/dist/brepjs.cjs +43 -311
- package/dist/brepjs.js +23 -306
- package/dist/core/errors.d.ts +7 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core.cjs +3 -3
- package/dist/core.js +3 -3
- package/dist/{cornerFinder-BSwshSGB.js → cornerFinder-C7aDyYLJ.js} +2 -2
- package/dist/{cornerFinder-sg0JNgux.cjs → cornerFinder-SF-xmMO1.cjs} +2 -2
- package/dist/{curveFns-D_s3LdNT.js → curveFns-C-jU1_Y_.js} +2 -2
- package/dist/{curveFns-CJjkUGyW.cjs → curveFns-ywh7Ctyk.cjs} +2 -2
- package/dist/{drawFns-oyqai_HD.js → drawFns-D-0p86Lf.js} +13 -13
- package/dist/{drawFns-0CYuQn0J.cjs → drawFns-DknEB-Qs.cjs} +13 -13
- package/dist/{errors-B1fl3mAU.js → errors-B_T0aMQF.js} +7 -0
- package/dist/{errors-C85KVJr-.cjs → errors-DupKEMqI.cjs} +7 -0
- package/dist/{extrudeFns-0kBZvqJz.cjs → extrudeFns-CGCIbydL.cjs} +2 -2
- package/dist/{extrudeFns-lDvV4ir2.js → extrudeFns-LsH1rDMa.js} +2 -2
- package/dist/{faceFns-8BurpAGN.cjs → faceFns-8dGb8q3J.cjs} +2 -2
- package/dist/{faceFns-Bne5RIvn.js → faceFns-EnGcKFAr.js} +2 -2
- package/dist/{helpers-CxexSe1n.js → helpers-Rf0vhX6I.js} +6 -6
- package/dist/{helpers-D8DIMw2U.cjs → helpers-pQpV9Mwh.cjs} +6 -6
- package/dist/{historyFns-BTeasREV.js → historyFns-XkjLAQyu.js} +5 -5
- package/dist/{historyFns-BAzQr6EP.cjs → historyFns-lNalnOdR.cjs} +5 -5
- package/dist/{importFns-D__wN_Pq.cjs → importFns-BSH9cGIp.cjs} +36 -4
- package/dist/{importFns-clldr3EF.js → importFns-Bgs-FYAP.js} +31 -5
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/io/stepConfigFns.d.ts +27 -0
- package/dist/io/stepConfigFns.d.ts.map +1 -0
- package/dist/io.cjs +3 -2
- package/dist/io.d.ts +1 -0
- package/dist/io.d.ts.map +1 -1
- package/dist/io.js +3 -3
- package/dist/kernel/brepkit/booleanOps.d.ts +7 -1
- package/dist/kernel/brepkit/booleanOps.d.ts.map +1 -1
- package/dist/kernel/brepkit/brepkitAdapter.d.ts +5 -4
- package/dist/kernel/brepkit/brepkitAdapter.d.ts.map +1 -1
- package/dist/kernel/brepkit/evolutionOps.d.ts +4 -4
- package/dist/kernel/brepkit/evolutionOps.d.ts.map +1 -1
- package/dist/kernel/interfaces/booleanOps.d.ts +3 -1
- package/dist/kernel/interfaces/booleanOps.d.ts.map +1 -1
- package/dist/kernel/interfaces/evolutionOps.d.ts +4 -4
- package/dist/kernel/interfaces/evolutionOps.d.ts.map +1 -1
- package/dist/kernel/occt/booleanOps.d.ts +7 -1
- package/dist/kernel/occt/booleanOps.d.ts.map +1 -1
- package/dist/kernel/occt/defaultAdapter.d.ts +5 -4
- package/dist/kernel/occt/defaultAdapter.d.ts.map +1 -1
- package/dist/kernel/occt/evolutionOps.d.ts +2 -2
- package/dist/kernel/occt/evolutionOps.d.ts.map +1 -1
- package/dist/kernel/occt/historyOps.d.ts +4 -4
- package/dist/kernel/occt/historyOps.d.ts.map +1 -1
- package/dist/kernel/occt/wasmTypes/occtBuilders.d.ts +4 -0
- package/dist/kernel/occt/wasmTypes/occtBuilders.d.ts.map +1 -1
- package/dist/kernel/types.d.ts +30 -0
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/{measureFns-DrMZGJ6r.cjs → measureFns-CFdHa_fj.cjs} +3 -3
- package/dist/{measureFns-C4WqH4OT.js → measureFns-D7J6qUY_.js} +3 -3
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-DvOM43vV.cjs → meshFns-2XnDXgIh.cjs} +3 -3
- package/dist/{meshFns--M5PTyHG.js → meshFns-B7uklc4M.js} +3 -3
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +2 -2
- package/dist/{planeOps-DPintPbl.js → planeOps-BuBXTLBr.js} +1 -1
- package/dist/{planeOps-DdkIuVjk.cjs → planeOps-cTxDywpG.cjs} +1 -1
- package/dist/primitiveFns-CASk8g16.js +1452 -0
- package/dist/primitiveFns-DKtvEA0i.cjs +1817 -0
- package/dist/query.cjs +2 -2
- package/dist/query.js +2 -2
- package/dist/result.cjs +1 -1
- package/dist/result.js +1 -1
- package/dist/{shapeTypes-GmE4D5Q_.cjs → shapeTypes-CElaawp7.cjs} +114 -9
- package/dist/{shapeTypes-D38b_BKF.js → shapeTypes-CYb8Byqj.js} +114 -9
- package/dist/sketching.cjs +2 -2
- package/dist/sketching.js +2 -2
- package/dist/{solidBuilders-FaTmd_PS.js → solidBuilders-ClJxiUa3.js} +3 -3
- package/dist/{solidBuilders-BqU0oT2q.cjs → solidBuilders-Cs4XyL58.cjs} +3 -3
- package/dist/{surfaceBuilders-DiCVk_Un.js → surfaceBuilders-DnGdDW8i.js} +3 -3
- package/dist/{surfaceBuilders-BzDQQ4EG.cjs → surfaceBuilders-ZUTb3z6i.cjs} +3 -3
- package/dist/topology/booleanDiagnosticFns.d.ts +18 -0
- package/dist/topology/booleanDiagnosticFns.d.ts.map +1 -0
- package/dist/topology/booleanFns.d.ts.map +1 -1
- package/dist/topology/evolutionFns.d.ts +71 -0
- package/dist/topology/evolutionFns.d.ts.map +1 -0
- package/dist/topology/healingFns.d.ts +17 -0
- package/dist/topology/healingFns.d.ts.map +1 -1
- package/dist/topology/modifierFns.d.ts +15 -0
- package/dist/topology/modifierFns.d.ts.map +1 -1
- package/dist/topology/positionFns.d.ts +15 -0
- package/dist/topology/positionFns.d.ts.map +1 -0
- package/dist/topology.cjs +18 -6
- package/dist/topology.d.ts +6 -1
- package/dist/topology.d.ts.map +1 -1
- package/dist/topology.js +7 -7
- package/dist/vectors.cjs +1 -1
- package/dist/vectors.js +1 -1
- package/package.json +1 -1
- package/dist/primitiveFns-BXufrcii.cjs +0 -1063
- package/dist/primitiveFns-u3Bbdvlw.js +0 -806
|
@@ -1,1063 +0,0 @@
|
|
|
1
|
-
const require_shapeTypes = require("./shapeTypes-GmE4D5Q_.cjs");
|
|
2
|
-
const require_errors = require("./errors-C85KVJr-.cjs");
|
|
3
|
-
const require_vecOps = require("./vecOps-4iBMiet9.cjs");
|
|
4
|
-
const require_faceFns = require("./faceFns-8BurpAGN.cjs");
|
|
5
|
-
const require_arrayAccess = require("./arrayAccess-BF8Hm4-H.cjs");
|
|
6
|
-
const require_surfaceBuilders = require("./surfaceBuilders-BzDQQ4EG.cjs");
|
|
7
|
-
const require_solidBuilders = require("./solidBuilders-BqU0oT2q.cjs");
|
|
8
|
-
//#region src/topology/threeHelpers.ts
|
|
9
|
-
/**
|
|
10
|
-
* Convert a ShapeMesh into BufferGeometry-compatible typed arrays.
|
|
11
|
-
*
|
|
12
|
-
* The returned arrays can be used directly with Three.js:
|
|
13
|
-
* ```ts
|
|
14
|
-
* const geo = new THREE.BufferGeometry();
|
|
15
|
-
* geo.setAttribute('position', new THREE.BufferAttribute(data.position, 3));
|
|
16
|
-
* geo.setAttribute('normal', new THREE.BufferAttribute(data.normal, 3));
|
|
17
|
-
* geo.setIndex(new THREE.BufferAttribute(data.index, 1));
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
function toBufferGeometryData(mesh) {
|
|
21
|
-
return {
|
|
22
|
-
position: mesh.vertices,
|
|
23
|
-
normal: mesh.normals,
|
|
24
|
-
index: mesh.triangles
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Convert a ShapeMesh into grouped BufferGeometry data with face material groups.
|
|
29
|
-
*
|
|
30
|
-
* Each face becomes a separate group, allowing per-face materials in Three.js:
|
|
31
|
-
* ```ts
|
|
32
|
-
* const data = toGroupedBufferGeometryData(mesh);
|
|
33
|
-
* const geo = new THREE.BufferGeometry();
|
|
34
|
-
* geo.setAttribute('position', new THREE.BufferAttribute(data.position, 3));
|
|
35
|
-
* geo.setAttribute('normal', new THREE.BufferAttribute(data.normal, 3));
|
|
36
|
-
* geo.setIndex(new THREE.BufferAttribute(data.index, 1));
|
|
37
|
-
* for (const g of data.groups) {
|
|
38
|
-
* geo.addGroup(g.start, g.count, g.materialIndex);
|
|
39
|
-
* }
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
function toGroupedBufferGeometryData(mesh) {
|
|
43
|
-
return {
|
|
44
|
-
position: mesh.vertices,
|
|
45
|
-
normal: mesh.normals,
|
|
46
|
-
index: mesh.triangles,
|
|
47
|
-
groups: mesh.faceGroups.map((g, i) => ({
|
|
48
|
-
start: g.start,
|
|
49
|
-
count: g.count,
|
|
50
|
-
materialIndex: i,
|
|
51
|
-
faceId: g.faceId
|
|
52
|
-
}))
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Convert an EdgeMesh into position data for THREE.LineSegments.
|
|
57
|
-
*
|
|
58
|
-
* ```ts
|
|
59
|
-
* const geo = new THREE.BufferGeometry();
|
|
60
|
-
* geo.setAttribute('position', new THREE.BufferAttribute(data.position, 3));
|
|
61
|
-
* const lines = new THREE.LineSegments(geo, material);
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
function toLineGeometryData(mesh) {
|
|
65
|
-
return { position: mesh.lines };
|
|
66
|
-
}
|
|
67
|
-
//#endregion
|
|
68
|
-
//#region src/topology/chamferAngleFns.ts
|
|
69
|
-
/**
|
|
70
|
-
* Chamfer with distance + angle — functional API.
|
|
71
|
-
*
|
|
72
|
-
* Provides chamferDistAngle() which chamfers edges using a distance
|
|
73
|
-
* measured along one face and an angle to determine the chamfer on the other.
|
|
74
|
-
*/
|
|
75
|
-
/**
|
|
76
|
-
* Chamfer edges of a shape using distance + angle.
|
|
77
|
-
*
|
|
78
|
-
* The distance is measured along the face that contains the edge, and the
|
|
79
|
-
* angle (in degrees) determines how the chamfer cuts into the adjacent face.
|
|
80
|
-
*
|
|
81
|
-
* @param shape - The 3D shape to chamfer.
|
|
82
|
-
* @param edges - Edges to chamfer (must not be empty).
|
|
83
|
-
* @param distance - Chamfer distance along the face (must be positive).
|
|
84
|
-
* @param angleDeg - Chamfer angle in degrees (must be in range (0, 90)).
|
|
85
|
-
* @returns Ok with the chamfered shape, or Err on invalid input or kernel failure.
|
|
86
|
-
*
|
|
87
|
-
* @remarks Uses `BRepFilletAPI_MakeChamfer.AddDA(dist, angle, edge, face)` internally.
|
|
88
|
-
*/
|
|
89
|
-
function chamferDistAngle(shape, edges, distance, angleDeg) {
|
|
90
|
-
if (edges.length === 0) return require_errors.err(require_errors.validationError("CHAMFER_ANGLE_NO_EDGES", "chamferDistAngle requires at least one edge", void 0, { edgeCount: 0 }));
|
|
91
|
-
if (distance <= 0) return require_errors.err(require_errors.validationError("CHAMFER_ANGLE_BAD_DISTANCE", `distance must be positive, got ${distance}`, void 0, { distance }));
|
|
92
|
-
if (angleDeg <= 0 || angleDeg >= 90) return require_errors.err(require_errors.validationError("CHAMFER_ANGLE_BAD_ANGLE", `angleDeg must be in range (0, 90), got ${angleDeg}`, void 0, { angleDeg }));
|
|
93
|
-
let raw;
|
|
94
|
-
try {
|
|
95
|
-
const kernel = require_shapeTypes.getKernel();
|
|
96
|
-
const rawEdges = edges.map((e) => e.wrapped);
|
|
97
|
-
raw = kernel.chamferDistAngle(shape.wrapped, rawEdges, distance, angleDeg);
|
|
98
|
-
} catch (e) {
|
|
99
|
-
return require_errors.err(require_errors.kernelError("CHAMFER_ANGLE_FAILED", `chamferDistAngle kernel call failed: ${e instanceof Error ? e.message : String(e)}`, e, {
|
|
100
|
-
distance,
|
|
101
|
-
angleDeg,
|
|
102
|
-
edgeCount: edges.length
|
|
103
|
-
}));
|
|
104
|
-
}
|
|
105
|
-
const downcastResult = require_faceFns.downcast(raw);
|
|
106
|
-
if (require_errors.isErr(downcastResult)) return downcastResult;
|
|
107
|
-
const wrapped = require_shapeTypes.castShape(downcastResult.value);
|
|
108
|
-
if (!require_shapeTypes.isShape3D(wrapped)) {
|
|
109
|
-
wrapped[Symbol.dispose]();
|
|
110
|
-
return require_errors.err(require_errors.typeCastError("CHAMFER_ANGLE_NOT_3D", "chamferDistAngle did not produce a 3D shape"));
|
|
111
|
-
}
|
|
112
|
-
return require_errors.ok(wrapped);
|
|
113
|
-
}
|
|
114
|
-
//#endregion
|
|
115
|
-
//#region src/topology/adjacencyFns.ts
|
|
116
|
-
/**
|
|
117
|
-
* Topology adjacency queries — find related sub-shapes within a parent shape.
|
|
118
|
-
*
|
|
119
|
-
* Uses cached topology extraction and an edge→faces adjacency map
|
|
120
|
-
* (built once per parent shape and cached) to avoid redundant WASM calls.
|
|
121
|
-
*/
|
|
122
|
-
function wrapAll(shapes, type) {
|
|
123
|
-
return shapes.map((s) => require_shapeTypes.castShapeWithKnownType(s, type));
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Iterate sub-shapes of `parentKernel` of the given `type`, deduplicate by
|
|
127
|
-
* hash+isSame, and return branded handles of type `T`.
|
|
128
|
-
*
|
|
129
|
-
* Used by edgesOfFace, wiresOfFace, and verticesOfEdge — all of which need
|
|
130
|
-
* the same deduplicated-children pattern on a raw KernelShape.
|
|
131
|
-
*/
|
|
132
|
-
function deduplicatedSubShapes(parentKernel, type) {
|
|
133
|
-
const kernel = require_shapeTypes.getKernel();
|
|
134
|
-
const items = kernel.iterShapes(parentKernel, type);
|
|
135
|
-
const results = [];
|
|
136
|
-
const seen = /* @__PURE__ */ new Map();
|
|
137
|
-
for (const item of items) {
|
|
138
|
-
const hash = kernel.hashCode(item, require_vecOps.HASH_CODE_MAX);
|
|
139
|
-
const bucket = seen.get(hash);
|
|
140
|
-
if (!bucket) {
|
|
141
|
-
seen.set(hash, [item]);
|
|
142
|
-
results.push(item);
|
|
143
|
-
} else if (!bucket.some((r) => kernel.isSame(r, item))) {
|
|
144
|
-
bucket.push(item);
|
|
145
|
-
results.push(item);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return wrapAll(results, type);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Build or retrieve the cached edge→faces adjacency map for a parent shape.
|
|
152
|
-
* Maps edge hash codes to edge-face pairs, storing the edge alongside each
|
|
153
|
-
* face so facesOfEdge can verify via isSame without re-extracting face edges.
|
|
154
|
-
*/
|
|
155
|
-
function getEdgeToFacesMap(parent) {
|
|
156
|
-
const cache = require_arrayAccess.getOrCreateCache(parent);
|
|
157
|
-
if (cache.edgeToFaces) return cache.edgeToFaces;
|
|
158
|
-
const kernel = require_shapeTypes.getKernel();
|
|
159
|
-
const edgeToFaces = /* @__PURE__ */ new Map();
|
|
160
|
-
const allFaces = kernel.iterShapes(parent.wrapped, "face");
|
|
161
|
-
for (const f of allFaces) {
|
|
162
|
-
const edges = kernel.iterShapes(f, "edge");
|
|
163
|
-
for (const e of edges) {
|
|
164
|
-
const hash = kernel.hashCode(e, require_vecOps.HASH_CODE_MAX);
|
|
165
|
-
let bucket = edgeToFaces.get(hash);
|
|
166
|
-
if (!bucket) {
|
|
167
|
-
bucket = [];
|
|
168
|
-
edgeToFaces.set(hash, bucket);
|
|
169
|
-
}
|
|
170
|
-
if (!bucket.some((entry) => kernel.isSame(entry.edge, e) && kernel.isSame(entry.face, f))) bucket.push({
|
|
171
|
-
edge: e,
|
|
172
|
-
face: f
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
cache.edgeToFaces = edgeToFaces;
|
|
177
|
-
return edgeToFaces;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Get all faces adjacent to a given edge within a parent shape.
|
|
181
|
-
*
|
|
182
|
-
* An edge typically borders exactly two faces in a solid, or one face
|
|
183
|
-
* if the edge is on a boundary.
|
|
184
|
-
*
|
|
185
|
-
* @param parent - The parent shape to search within.
|
|
186
|
-
* @param edge - The edge whose adjacent faces to find.
|
|
187
|
-
* @returns Array of unique faces containing the given edge.
|
|
188
|
-
*/
|
|
189
|
-
function facesOfEdge(parent, edge) {
|
|
190
|
-
const kernel = require_shapeTypes.getKernel();
|
|
191
|
-
const edgeToFaces = getEdgeToFacesMap(parent);
|
|
192
|
-
const hash = kernel.hashCode(edge.wrapped, require_vecOps.HASH_CODE_MAX);
|
|
193
|
-
const bucket = edgeToFaces.get(hash) ?? [];
|
|
194
|
-
const results = [];
|
|
195
|
-
const seen = /* @__PURE__ */ new Map();
|
|
196
|
-
for (const entry of bucket) {
|
|
197
|
-
if (!kernel.isSame(entry.edge, edge.wrapped)) continue;
|
|
198
|
-
const fHash = kernel.hashCode(entry.face, require_vecOps.HASH_CODE_MAX);
|
|
199
|
-
const fBucket = seen.get(fHash);
|
|
200
|
-
if (!fBucket) {
|
|
201
|
-
seen.set(fHash, [entry.face]);
|
|
202
|
-
results.push(entry.face);
|
|
203
|
-
} else if (!fBucket.some((r) => kernel.isSame(r, entry.face))) {
|
|
204
|
-
fBucket.push(entry.face);
|
|
205
|
-
results.push(entry.face);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return wrapAll(results, "face");
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Get all edges bounding a face.
|
|
212
|
-
*
|
|
213
|
-
* @param face - The face whose edges to enumerate.
|
|
214
|
-
* @returns Array of unique edges forming the face boundary.
|
|
215
|
-
*/
|
|
216
|
-
function edgesOfFace(face) {
|
|
217
|
-
return deduplicatedSubShapes(face.wrapped, "edge");
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Get all wires of a face (outer wire + inner hole wires).
|
|
221
|
-
* All wires bounding a face are closed by definition.
|
|
222
|
-
*
|
|
223
|
-
* @param face - The face whose wires to enumerate.
|
|
224
|
-
*/
|
|
225
|
-
function wiresOfFace(face) {
|
|
226
|
-
return deduplicatedSubShapes(face.wrapped, "wire");
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Get the start and end vertices of an edge.
|
|
230
|
-
*
|
|
231
|
-
* @param edge - The edge whose vertices to retrieve.
|
|
232
|
-
* @returns Array of 1-2 vertices (1 if degenerate/closed, 2 otherwise).
|
|
233
|
-
*/
|
|
234
|
-
function verticesOfEdge(edge) {
|
|
235
|
-
return deduplicatedSubShapes(edge.wrapped, "vertex");
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Get all faces that share at least one edge with the given face.
|
|
239
|
-
*
|
|
240
|
-
* The returned list does not include the input face itself.
|
|
241
|
-
* Uses the cached edge→faces adjacency map for the parent shape.
|
|
242
|
-
*
|
|
243
|
-
* @param parent - The parent shape to search within.
|
|
244
|
-
* @param face - The face whose neighbors to find.
|
|
245
|
-
* @returns Array of unique adjacent faces (excluding the input face).
|
|
246
|
-
*/
|
|
247
|
-
function adjacentFaces(parent, face) {
|
|
248
|
-
const kernel = require_shapeTypes.getKernel();
|
|
249
|
-
const edgeToFaces = getEdgeToFacesMap(parent);
|
|
250
|
-
const faceEdgeHandles = deduplicatedSubShapes(face.wrapped, "edge");
|
|
251
|
-
const neighborRaw = [];
|
|
252
|
-
const seen = /* @__PURE__ */ new Map();
|
|
253
|
-
for (const edgeHandle of faceEdgeHandles) {
|
|
254
|
-
const hash = kernel.hashCode(edgeHandle.wrapped, require_vecOps.HASH_CODE_MAX);
|
|
255
|
-
const entries = edgeToFaces.get(hash) ?? [];
|
|
256
|
-
for (const entry of entries) {
|
|
257
|
-
if (kernel.isSame(entry.face, face.wrapped)) continue;
|
|
258
|
-
const fHash = kernel.hashCode(entry.face, require_vecOps.HASH_CODE_MAX);
|
|
259
|
-
const bucket = seen.get(fHash);
|
|
260
|
-
if (!bucket) {
|
|
261
|
-
seen.set(fHash, [entry.face]);
|
|
262
|
-
neighborRaw.push(entry.face);
|
|
263
|
-
} else if (!bucket.some((r) => kernel.isSame(r, entry.face))) {
|
|
264
|
-
bucket.push(entry.face);
|
|
265
|
-
neighborRaw.push(entry.face);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
return wrapAll(neighborRaw, "face");
|
|
270
|
-
}
|
|
271
|
-
/**
|
|
272
|
-
* Get all edges shared between two faces.
|
|
273
|
-
*
|
|
274
|
-
* @param face1 - The first face.
|
|
275
|
-
* @param face2 - The second face.
|
|
276
|
-
* @returns Array of edges present in both faces (via isSame comparison).
|
|
277
|
-
*/
|
|
278
|
-
function sharedEdges(face1, face2) {
|
|
279
|
-
const kernel = require_shapeTypes.getKernel();
|
|
280
|
-
const edges1 = kernel.iterShapes(face1.wrapped, "edge");
|
|
281
|
-
const edges2 = kernel.iterShapes(face2.wrapped, "edge");
|
|
282
|
-
const edge2Map = /* @__PURE__ */ new Map();
|
|
283
|
-
for (const e2 of edges2) {
|
|
284
|
-
const hash = kernel.hashCode(e2, require_vecOps.HASH_CODE_MAX);
|
|
285
|
-
let bucket = edge2Map.get(hash);
|
|
286
|
-
if (!bucket) {
|
|
287
|
-
bucket = [];
|
|
288
|
-
edge2Map.set(hash, bucket);
|
|
289
|
-
}
|
|
290
|
-
bucket.push(e2);
|
|
291
|
-
}
|
|
292
|
-
const shared = [];
|
|
293
|
-
for (const e1 of edges1) if (edge2Map.get(kernel.hashCode(e1, 2147483647))?.some((e2) => kernel.isSame(e1, e2))) shared.push(e1);
|
|
294
|
-
return wrapAll(shared, "edge");
|
|
295
|
-
}
|
|
296
|
-
//#endregion
|
|
297
|
-
//#region src/topology/healingFns.ts
|
|
298
|
-
/**
|
|
299
|
-
* Shape healing and validation functions.
|
|
300
|
-
*
|
|
301
|
-
* Uses ShapeFix_Solid, ShapeFix_Face, ShapeFix_Wire, and BRepCheck_Analyzer
|
|
302
|
-
* to validate and repair shapes.
|
|
303
|
-
*/
|
|
304
|
-
/**
|
|
305
|
-
* Check if a shape is valid according to kernel geometry and topology checks.
|
|
306
|
-
*/
|
|
307
|
-
function isValid(shape) {
|
|
308
|
-
return require_shapeTypes.getKernel().isValid(shape.wrapped);
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Attempt to heal/fix a solid shape.
|
|
312
|
-
*
|
|
313
|
-
* Uses ShapeFix_Solid to repair topology issues like gaps, wrong orientation, etc.
|
|
314
|
-
*/
|
|
315
|
-
function healSolid(solid) {
|
|
316
|
-
if (!require_shapeTypes.isSolid(solid)) return require_errors.err(require_errors.validationError("NOT_A_SOLID", "Input shape is not a solid"));
|
|
317
|
-
const alreadyValid = isValid(solid);
|
|
318
|
-
try {
|
|
319
|
-
const result = require_shapeTypes.getKernel().healSolid(solid.wrapped);
|
|
320
|
-
if (!result) {
|
|
321
|
-
if (alreadyValid) return require_errors.ok(solid);
|
|
322
|
-
return require_errors.err(require_errors.kernelError(require_errors.BrepErrorCode.HEAL_NO_EFFECT, "Solid healing had no effect — shape is still invalid"));
|
|
323
|
-
}
|
|
324
|
-
const cast = require_shapeTypes.castShape(result);
|
|
325
|
-
if (!require_shapeTypes.isSolid(cast)) return require_errors.err(require_errors.kernelError("HEAL_RESULT_NOT_SOLID", "Healed result is not a solid"));
|
|
326
|
-
if (!isValid(cast)) return require_errors.err(require_errors.kernelError("HEAL_SOLID_INCOMPLETE", "Healed result is still invalid after ShapeFix_Solid"));
|
|
327
|
-
return require_errors.ok(cast);
|
|
328
|
-
} catch (e) {
|
|
329
|
-
return require_errors.err(require_errors.kernelError("HEAL_SOLID_FAILED", "Solid healing failed", e));
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Attempt to heal/fix a face.
|
|
334
|
-
*
|
|
335
|
-
* Uses ShapeFix_Face to repair wire ordering, orientation, and geometry issues.
|
|
336
|
-
*/
|
|
337
|
-
function healFace(face) {
|
|
338
|
-
if (!require_shapeTypes.isFace(face)) return require_errors.err(require_errors.validationError("NOT_A_FACE", "Input shape is not a face"));
|
|
339
|
-
try {
|
|
340
|
-
const cast = require_shapeTypes.castShape(require_shapeTypes.getKernel().healFace(face.wrapped));
|
|
341
|
-
if (!require_shapeTypes.isFace(cast)) return require_errors.err(require_errors.kernelError("HEAL_RESULT_NOT_FACE", "Healed result is not a face"));
|
|
342
|
-
return require_errors.ok(cast);
|
|
343
|
-
} catch (e) {
|
|
344
|
-
return require_errors.err(require_errors.kernelError("HEAL_FACE_FAILED", "Face healing failed", e));
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Attempt to heal/fix a wire.
|
|
349
|
-
*
|
|
350
|
-
* Uses ShapeFix_Wire to repair edge connectivity, gaps, and self-intersections.
|
|
351
|
-
* Requires a face for surface context; pass `undefined` to use a default planar context.
|
|
352
|
-
*/
|
|
353
|
-
function healWire(wire, face) {
|
|
354
|
-
if (!require_shapeTypes.isWire(wire)) return require_errors.err(require_errors.validationError("NOT_A_WIRE", "Input shape is not a wire"));
|
|
355
|
-
try {
|
|
356
|
-
const cast = require_shapeTypes.castShape(require_shapeTypes.getKernel().healWire(wire.wrapped, face?.wrapped));
|
|
357
|
-
if (!require_shapeTypes.isWire(cast)) return require_errors.err(require_errors.kernelError("HEAL_RESULT_NOT_WIRE", "Healed result is not a wire"));
|
|
358
|
-
return require_errors.ok(cast);
|
|
359
|
-
} catch (e) {
|
|
360
|
-
return require_errors.err(require_errors.kernelError("HEAL_WIRE_FAILED", "Wire healing failed", e));
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Attempt to heal any shape by dispatching to the appropriate fixer.
|
|
365
|
-
*
|
|
366
|
-
* Supports solids, faces, and wires. For other shape types, returns the
|
|
367
|
-
* input unchanged.
|
|
368
|
-
*/
|
|
369
|
-
function heal(shape) {
|
|
370
|
-
if (require_shapeTypes.isSolid(shape)) return healSolid(shape);
|
|
371
|
-
if (require_shapeTypes.isFace(shape)) return healFace(shape);
|
|
372
|
-
if (require_shapeTypes.isWire(shape)) return healWire(shape);
|
|
373
|
-
return require_errors.ok(shape);
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Automatically heal a shape using the appropriate shape-level fixer.
|
|
377
|
-
*
|
|
378
|
-
* If the shape is already valid, returns it unchanged with a no-op report.
|
|
379
|
-
* Uses ShapeFix_Solid/Face/Wire depending on shape type, which internally
|
|
380
|
-
* handles sub-shape healing and reconstruction.
|
|
381
|
-
*/
|
|
382
|
-
function autoHeal(shape, options) {
|
|
383
|
-
const fixWires = options?.fixWires !== false;
|
|
384
|
-
const fixFaces = options?.fixFaces !== false;
|
|
385
|
-
const fixSolids = options?.fixSolids !== false;
|
|
386
|
-
const fixSelfIntersection = options?.fixSelfIntersection === true;
|
|
387
|
-
const sewTolerance = options?.sewTolerance;
|
|
388
|
-
const steps = [];
|
|
389
|
-
const diagnostics = [];
|
|
390
|
-
if (isValid(shape)) return require_errors.ok({
|
|
391
|
-
shape,
|
|
392
|
-
report: {
|
|
393
|
-
isValid: true,
|
|
394
|
-
alreadyValid: true,
|
|
395
|
-
wiresHealed: 0,
|
|
396
|
-
facesHealed: 0,
|
|
397
|
-
solidHealed: false,
|
|
398
|
-
steps: ["Shape already valid"],
|
|
399
|
-
diagnostics: [{
|
|
400
|
-
name: "validation",
|
|
401
|
-
attempted: true,
|
|
402
|
-
succeeded: true
|
|
403
|
-
}]
|
|
404
|
-
}
|
|
405
|
-
});
|
|
406
|
-
steps.push("Shape invalid — applying shape-level healing");
|
|
407
|
-
const wiresBefore = require_arrayAccess.getWires(shape).length;
|
|
408
|
-
const facesBefore = require_arrayAccess.getFaces(shape).length;
|
|
409
|
-
let current = shape;
|
|
410
|
-
let solidHealed = false;
|
|
411
|
-
if (sewTolerance !== void 0) try {
|
|
412
|
-
current = require_shapeTypes.castShape(require_shapeTypes.getKernel().sew([current.wrapped], sewTolerance));
|
|
413
|
-
steps.push(`Applied sewing with tolerance ${sewTolerance}`);
|
|
414
|
-
diagnostics.push({
|
|
415
|
-
name: "sew",
|
|
416
|
-
attempted: true,
|
|
417
|
-
succeeded: true,
|
|
418
|
-
detail: `tolerance=${sewTolerance}`
|
|
419
|
-
});
|
|
420
|
-
} catch (e) {
|
|
421
|
-
const detail = e instanceof Error ? e.message : String(e);
|
|
422
|
-
steps.push(`Sewing failed: ${detail}`);
|
|
423
|
-
diagnostics.push({
|
|
424
|
-
name: "sew",
|
|
425
|
-
attempted: true,
|
|
426
|
-
succeeded: false,
|
|
427
|
-
detail
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
if (fixSelfIntersection && fixWires) {
|
|
431
|
-
const wires = require_arrayAccess.getWires(current);
|
|
432
|
-
let fixCount = 0;
|
|
433
|
-
for (const wire of wires) try {
|
|
434
|
-
require_shapeTypes.getKernel().fixSelfIntersection(wire.wrapped);
|
|
435
|
-
fixCount++;
|
|
436
|
-
} catch {}
|
|
437
|
-
steps.push(`Self-intersection fix: ${fixCount}/${wires.length} wires`);
|
|
438
|
-
diagnostics.push({
|
|
439
|
-
name: "fixSelfIntersection",
|
|
440
|
-
attempted: true,
|
|
441
|
-
succeeded: fixCount > 0,
|
|
442
|
-
detail: `${fixCount}/${wires.length} wires fixed`
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
if (require_shapeTypes.isSolid(current) && fixSolids || require_shapeTypes.isFace(current) && fixFaces || require_shapeTypes.isWire(current) && fixWires) {
|
|
446
|
-
const healResult = heal(current);
|
|
447
|
-
if (require_errors.isOk(healResult)) {
|
|
448
|
-
current = healResult.value;
|
|
449
|
-
if (require_shapeTypes.isSolid(shape)) {
|
|
450
|
-
solidHealed = true;
|
|
451
|
-
steps.push("Applied ShapeFix_Solid");
|
|
452
|
-
diagnostics.push({
|
|
453
|
-
name: "healSolid",
|
|
454
|
-
attempted: true,
|
|
455
|
-
succeeded: true
|
|
456
|
-
});
|
|
457
|
-
} else if (require_shapeTypes.isFace(shape)) {
|
|
458
|
-
steps.push("Applied ShapeFix_Face");
|
|
459
|
-
diagnostics.push({
|
|
460
|
-
name: "healFace",
|
|
461
|
-
attempted: true,
|
|
462
|
-
succeeded: true
|
|
463
|
-
});
|
|
464
|
-
} else {
|
|
465
|
-
steps.push("Applied ShapeFix_Wire");
|
|
466
|
-
diagnostics.push({
|
|
467
|
-
name: "healWire",
|
|
468
|
-
attempted: true,
|
|
469
|
-
succeeded: true
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
} else {
|
|
473
|
-
steps.push("Shape-level healing failed");
|
|
474
|
-
diagnostics.push({
|
|
475
|
-
name: "healShape",
|
|
476
|
-
attempted: true,
|
|
477
|
-
succeeded: false
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
} else diagnostics.push({
|
|
481
|
-
name: "healShape",
|
|
482
|
-
attempted: false,
|
|
483
|
-
succeeded: false,
|
|
484
|
-
detail: "skipped by options"
|
|
485
|
-
});
|
|
486
|
-
const wiresAfter = require_arrayAccess.getWires(current).length;
|
|
487
|
-
const facesAfter = require_arrayAccess.getFaces(current).length;
|
|
488
|
-
const wiresHealed = Math.abs(wiresAfter - wiresBefore);
|
|
489
|
-
const facesHealed = Math.abs(facesAfter - facesBefore);
|
|
490
|
-
if (wiresHealed > 0) steps.push(`Wire count changed by ${wiresHealed}`);
|
|
491
|
-
if (facesHealed > 0) steps.push(`Face count changed by ${facesHealed}`);
|
|
492
|
-
const valid = isValid(current);
|
|
493
|
-
steps.push(valid ? "Final validation: valid" : "Final validation: still invalid");
|
|
494
|
-
diagnostics.push({
|
|
495
|
-
name: "finalValidation",
|
|
496
|
-
attempted: true,
|
|
497
|
-
succeeded: valid
|
|
498
|
-
});
|
|
499
|
-
return require_errors.ok({
|
|
500
|
-
shape: current,
|
|
501
|
-
report: {
|
|
502
|
-
isValid: valid,
|
|
503
|
-
alreadyValid: false,
|
|
504
|
-
wiresHealed,
|
|
505
|
-
facesHealed,
|
|
506
|
-
solidHealed,
|
|
507
|
-
steps,
|
|
508
|
-
diagnostics
|
|
509
|
-
}
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
//#endregion
|
|
513
|
-
//#region src/topology/primitiveFns.ts
|
|
514
|
-
/**
|
|
515
|
-
* Create a box with the given dimensions.
|
|
516
|
-
*
|
|
517
|
-
* @param width - Size along X.
|
|
518
|
-
* @param depth - Size along Y.
|
|
519
|
-
* @param height - Size along Z.
|
|
520
|
-
*/
|
|
521
|
-
function box(width, depth, height, options) {
|
|
522
|
-
const solid = require_shapeTypes.createSolid(require_shapeTypes.getKernel().makeBox(width, depth, height));
|
|
523
|
-
const center = options?.at ?? (options?.centered ? [
|
|
524
|
-
0,
|
|
525
|
-
0,
|
|
526
|
-
0
|
|
527
|
-
] : void 0);
|
|
528
|
-
if (center) return require_arrayAccess.translate(solid, [
|
|
529
|
-
center[0] - width / 2,
|
|
530
|
-
center[1] - depth / 2,
|
|
531
|
-
center[2] - height / 2
|
|
532
|
-
]);
|
|
533
|
-
return solid;
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Create a cylinder with the given radius and height.
|
|
537
|
-
*/
|
|
538
|
-
function cylinder(radius, height, options) {
|
|
539
|
-
const at = options?.at ?? [
|
|
540
|
-
0,
|
|
541
|
-
0,
|
|
542
|
-
0
|
|
543
|
-
];
|
|
544
|
-
const axis = options?.axis ?? [
|
|
545
|
-
0,
|
|
546
|
-
0,
|
|
547
|
-
1
|
|
548
|
-
];
|
|
549
|
-
let solid = require_solidBuilders.makeCylinder(radius, height, at, axis);
|
|
550
|
-
if (options?.centered) {
|
|
551
|
-
const halfShift = [
|
|
552
|
-
-axis[0] * height * .5,
|
|
553
|
-
-axis[1] * height * .5,
|
|
554
|
-
-axis[2] * height * .5
|
|
555
|
-
];
|
|
556
|
-
solid = require_arrayAccess.translate(solid, halfShift);
|
|
557
|
-
}
|
|
558
|
-
return solid;
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Create a sphere with the given radius.
|
|
562
|
-
*/
|
|
563
|
-
function sphere(radius, options) {
|
|
564
|
-
let solid = require_solidBuilders.makeSphere(radius);
|
|
565
|
-
if (options?.at) solid = require_arrayAccess.translate(solid, options.at);
|
|
566
|
-
return solid;
|
|
567
|
-
}
|
|
568
|
-
/**
|
|
569
|
-
* Create a cone (or frustum) with the given radii and height.
|
|
570
|
-
*
|
|
571
|
-
* @param bottomRadius - Radius at the base.
|
|
572
|
-
* @param topRadius - Radius at the top (0 for a full cone).
|
|
573
|
-
* @param height - Height of the cone.
|
|
574
|
-
*/
|
|
575
|
-
function cone(bottomRadius, topRadius, height, options) {
|
|
576
|
-
const at = options?.at ?? [
|
|
577
|
-
0,
|
|
578
|
-
0,
|
|
579
|
-
0
|
|
580
|
-
];
|
|
581
|
-
const axis = options?.axis ?? [
|
|
582
|
-
0,
|
|
583
|
-
0,
|
|
584
|
-
1
|
|
585
|
-
];
|
|
586
|
-
let solid = require_solidBuilders.makeCone(bottomRadius, topRadius, height, at, axis);
|
|
587
|
-
if (options?.centered) {
|
|
588
|
-
const halfShift = [
|
|
589
|
-
-axis[0] * height * .5,
|
|
590
|
-
-axis[1] * height * .5,
|
|
591
|
-
-axis[2] * height * .5
|
|
592
|
-
];
|
|
593
|
-
solid = require_arrayAccess.translate(solid, halfShift);
|
|
594
|
-
}
|
|
595
|
-
return solid;
|
|
596
|
-
}
|
|
597
|
-
/**
|
|
598
|
-
* Create a torus with the given major and minor radii.
|
|
599
|
-
*/
|
|
600
|
-
function torus(majorRadius, minorRadius, options) {
|
|
601
|
-
return require_solidBuilders.makeTorus(majorRadius, minorRadius, options?.at ?? [
|
|
602
|
-
0,
|
|
603
|
-
0,
|
|
604
|
-
0
|
|
605
|
-
], options?.axis ?? [
|
|
606
|
-
0,
|
|
607
|
-
0,
|
|
608
|
-
1
|
|
609
|
-
]);
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Create an ellipsoid with the given axis half-lengths.
|
|
613
|
-
*
|
|
614
|
-
* @param rx - Half-length along X.
|
|
615
|
-
* @param ry - Half-length along Y.
|
|
616
|
-
* @param rz - Half-length along Z.
|
|
617
|
-
*/
|
|
618
|
-
function ellipsoid(rx, ry, rz, options) {
|
|
619
|
-
let solid = require_solidBuilders.makeEllipsoid(rx, ry, rz);
|
|
620
|
-
if (options?.at) solid = require_arrayAccess.translate(solid, options.at);
|
|
621
|
-
return solid;
|
|
622
|
-
}
|
|
623
|
-
/** Create a straight edge between two 3D points. */
|
|
624
|
-
function line(from, to) {
|
|
625
|
-
return require_surfaceBuilders.makeLine(from, to);
|
|
626
|
-
}
|
|
627
|
-
/** Create a circular edge with the given radius. */
|
|
628
|
-
function circle(radius, options) {
|
|
629
|
-
const axisDir = options?.axis ?? [
|
|
630
|
-
0,
|
|
631
|
-
0,
|
|
632
|
-
1
|
|
633
|
-
];
|
|
634
|
-
return require_surfaceBuilders.makeCircle(radius, options?.at ?? [
|
|
635
|
-
0,
|
|
636
|
-
0,
|
|
637
|
-
0
|
|
638
|
-
], axisDir);
|
|
639
|
-
}
|
|
640
|
-
/**
|
|
641
|
-
* Create an elliptical edge.
|
|
642
|
-
*
|
|
643
|
-
* @returns An error if `minorRadius` exceeds `majorRadius`.
|
|
644
|
-
*/
|
|
645
|
-
function ellipse(majorRadius, minorRadius, options) {
|
|
646
|
-
const axisDir = options?.axis ?? [
|
|
647
|
-
0,
|
|
648
|
-
0,
|
|
649
|
-
1
|
|
650
|
-
];
|
|
651
|
-
return require_surfaceBuilders.makeEllipse(majorRadius, minorRadius, options?.at ?? [
|
|
652
|
-
0,
|
|
653
|
-
0,
|
|
654
|
-
0
|
|
655
|
-
], axisDir, options?.xDir);
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* Create a helical wire.
|
|
659
|
-
*
|
|
660
|
-
* @param pitch - Vertical distance per full turn.
|
|
661
|
-
* @param height - Total height.
|
|
662
|
-
* @param radius - Helix radius.
|
|
663
|
-
*/
|
|
664
|
-
function helix(pitch, height, radius, options) {
|
|
665
|
-
return require_surfaceBuilders.makeHelix(pitch, height, radius, options?.at ?? [
|
|
666
|
-
0,
|
|
667
|
-
0,
|
|
668
|
-
0
|
|
669
|
-
], options?.axis ?? [
|
|
670
|
-
0,
|
|
671
|
-
0,
|
|
672
|
-
1
|
|
673
|
-
], options?.lefthand ?? false);
|
|
674
|
-
}
|
|
675
|
-
/** Create a circular arc edge passing through three points. */
|
|
676
|
-
function threePointArc(p1, p2, p3) {
|
|
677
|
-
return require_surfaceBuilders.makeThreePointArc(p1, p2, p3);
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
|
-
* Create an elliptical arc edge between two angles.
|
|
681
|
-
*
|
|
682
|
-
* All angles are in **degrees** (unlike the legacy `makeEllipseArc` which used radians).
|
|
683
|
-
*
|
|
684
|
-
* @param startAngle - Start angle in degrees.
|
|
685
|
-
* @param endAngle - End angle in degrees.
|
|
686
|
-
*/
|
|
687
|
-
function ellipseArc(majorRadius, minorRadius, startAngle, endAngle, options) {
|
|
688
|
-
const axisDir = options?.axis ?? [
|
|
689
|
-
0,
|
|
690
|
-
0,
|
|
691
|
-
1
|
|
692
|
-
];
|
|
693
|
-
return require_surfaceBuilders.makeEllipseArc(majorRadius, minorRadius, startAngle * require_vecOps.DEG2RAD, endAngle * require_vecOps.DEG2RAD, options?.at ?? [
|
|
694
|
-
0,
|
|
695
|
-
0,
|
|
696
|
-
0
|
|
697
|
-
], axisDir, options?.xDir);
|
|
698
|
-
}
|
|
699
|
-
/**
|
|
700
|
-
* Create a B-spline edge that approximates a set of 3D points.
|
|
701
|
-
*
|
|
702
|
-
* @returns An error if the approximation algorithm fails.
|
|
703
|
-
*/
|
|
704
|
-
function bsplineApprox(points, config) {
|
|
705
|
-
return require_surfaceBuilders.makeBSplineApproximation(points, config);
|
|
706
|
-
}
|
|
707
|
-
/**
|
|
708
|
-
* Create a Bezier curve edge from control points.
|
|
709
|
-
*
|
|
710
|
-
* @param points - Two or more control points.
|
|
711
|
-
*/
|
|
712
|
-
function bezier(points) {
|
|
713
|
-
return require_surfaceBuilders.makeBezierCurve(points);
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* Create a circular arc edge tangent to a direction at the start point.
|
|
717
|
-
*/
|
|
718
|
-
function tangentArc(startPoint, startTgt, endPoint) {
|
|
719
|
-
return require_surfaceBuilders.makeTangentArc(startPoint, startTgt, endPoint);
|
|
720
|
-
}
|
|
721
|
-
/**
|
|
722
|
-
* Assemble edges and/or wires into a single connected wire.
|
|
723
|
-
*/
|
|
724
|
-
function wire(listOfEdges) {
|
|
725
|
-
return require_surfaceBuilders.assembleWire(listOfEdges);
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Assemble edges into a wire and verify it forms a closed loop.
|
|
729
|
-
*
|
|
730
|
-
* Combines {@link wire} + the `closedWire` smart constructor in a single step.
|
|
731
|
-
* Returns an error if the edges cannot be assembled or the wire is not closed.
|
|
732
|
-
*
|
|
733
|
-
* @example
|
|
734
|
-
* ```ts
|
|
735
|
-
* const cw = unwrap(wireLoop([e1, e2, e3, e4]));
|
|
736
|
-
* const f = unwrap(face(cw)); // ClosedWire accepted directly
|
|
737
|
-
* ```
|
|
738
|
-
*/
|
|
739
|
-
function wireLoop(listOfEdges) {
|
|
740
|
-
return require_errors.andThen(require_surfaceBuilders.assembleWire(listOfEdges), (w) => {
|
|
741
|
-
if (require_shapeTypes.isClosedWire(w)) return require_errors.ok(w);
|
|
742
|
-
return require_errors.err(require_errors.validationError("WIRE_NOT_CLOSED", "Assembled wire is not closed: start and end points do not coincide"));
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
/**
|
|
746
|
-
* Create a planar face from a closed wire, optionally with holes.
|
|
747
|
-
* The resulting face is always oriented (consistent normal direction).
|
|
748
|
-
*/
|
|
749
|
-
function face(w, holes) {
|
|
750
|
-
return require_surfaceBuilders.makeFace(w, holes);
|
|
751
|
-
}
|
|
752
|
-
/**
|
|
753
|
-
* Create a non-planar face from a wire using surface filling.
|
|
754
|
-
* The resulting face is always oriented.
|
|
755
|
-
*/
|
|
756
|
-
function filledFace(w) {
|
|
757
|
-
return require_surfaceBuilders.makeNonPlanarFace(w);
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Create a face bounded by a wire on an existing face's surface.
|
|
761
|
-
* The resulting face inherits orientation from the origin face.
|
|
762
|
-
*/
|
|
763
|
-
function subFace(originFace, w) {
|
|
764
|
-
return require_surfaceBuilders.makeNewFaceWithinFace(originFace, w);
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* Create a polygonal face from three or more coplanar points.
|
|
768
|
-
* The resulting face is always oriented.
|
|
769
|
-
*/
|
|
770
|
-
function polygon(points) {
|
|
771
|
-
return require_surfaceBuilders.makePolygon(points);
|
|
772
|
-
}
|
|
773
|
-
/** Create a vertex at a 3D point. */
|
|
774
|
-
function vertex(point) {
|
|
775
|
-
return require_solidBuilders.makeVertex(point);
|
|
776
|
-
}
|
|
777
|
-
/**
|
|
778
|
-
* Build a compound from multiple shapes.
|
|
779
|
-
*/
|
|
780
|
-
function compound(shapeArray) {
|
|
781
|
-
return require_solidBuilders.makeCompound(shapeArray);
|
|
782
|
-
}
|
|
783
|
-
/**
|
|
784
|
-
* Weld faces and shells into a single solid.
|
|
785
|
-
* The resulting solid is always validated.
|
|
786
|
-
*/
|
|
787
|
-
function solid(facesOrShells) {
|
|
788
|
-
return require_solidBuilders.makeSolid(facesOrShells);
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Create an offset shape from a face.
|
|
792
|
-
*/
|
|
793
|
-
function offsetFace(f, distance, tolerance) {
|
|
794
|
-
return require_solidBuilders.makeOffset(f, distance, tolerance);
|
|
795
|
-
}
|
|
796
|
-
/**
|
|
797
|
-
* Weld faces and shells into a single shell.
|
|
798
|
-
*/
|
|
799
|
-
function sewShells(facesOrShells, ignoreType) {
|
|
800
|
-
return require_solidBuilders.weldShellsAndFaces(facesOrShells, ignoreType);
|
|
801
|
-
}
|
|
802
|
-
function addHoles(f, holes) {
|
|
803
|
-
return require_surfaceBuilders.addHolesInFace(f, holes);
|
|
804
|
-
}
|
|
805
|
-
//#endregion
|
|
806
|
-
Object.defineProperty(exports, "addHoles", {
|
|
807
|
-
enumerable: true,
|
|
808
|
-
get: function() {
|
|
809
|
-
return addHoles;
|
|
810
|
-
}
|
|
811
|
-
});
|
|
812
|
-
Object.defineProperty(exports, "adjacentFaces", {
|
|
813
|
-
enumerable: true,
|
|
814
|
-
get: function() {
|
|
815
|
-
return adjacentFaces;
|
|
816
|
-
}
|
|
817
|
-
});
|
|
818
|
-
Object.defineProperty(exports, "autoHeal", {
|
|
819
|
-
enumerable: true,
|
|
820
|
-
get: function() {
|
|
821
|
-
return autoHeal;
|
|
822
|
-
}
|
|
823
|
-
});
|
|
824
|
-
Object.defineProperty(exports, "bezier", {
|
|
825
|
-
enumerable: true,
|
|
826
|
-
get: function() {
|
|
827
|
-
return bezier;
|
|
828
|
-
}
|
|
829
|
-
});
|
|
830
|
-
Object.defineProperty(exports, "box", {
|
|
831
|
-
enumerable: true,
|
|
832
|
-
get: function() {
|
|
833
|
-
return box;
|
|
834
|
-
}
|
|
835
|
-
});
|
|
836
|
-
Object.defineProperty(exports, "bsplineApprox", {
|
|
837
|
-
enumerable: true,
|
|
838
|
-
get: function() {
|
|
839
|
-
return bsplineApprox;
|
|
840
|
-
}
|
|
841
|
-
});
|
|
842
|
-
Object.defineProperty(exports, "chamferDistAngle", {
|
|
843
|
-
enumerable: true,
|
|
844
|
-
get: function() {
|
|
845
|
-
return chamferDistAngle;
|
|
846
|
-
}
|
|
847
|
-
});
|
|
848
|
-
Object.defineProperty(exports, "circle", {
|
|
849
|
-
enumerable: true,
|
|
850
|
-
get: function() {
|
|
851
|
-
return circle;
|
|
852
|
-
}
|
|
853
|
-
});
|
|
854
|
-
Object.defineProperty(exports, "compound", {
|
|
855
|
-
enumerable: true,
|
|
856
|
-
get: function() {
|
|
857
|
-
return compound;
|
|
858
|
-
}
|
|
859
|
-
});
|
|
860
|
-
Object.defineProperty(exports, "cone", {
|
|
861
|
-
enumerable: true,
|
|
862
|
-
get: function() {
|
|
863
|
-
return cone;
|
|
864
|
-
}
|
|
865
|
-
});
|
|
866
|
-
Object.defineProperty(exports, "cylinder", {
|
|
867
|
-
enumerable: true,
|
|
868
|
-
get: function() {
|
|
869
|
-
return cylinder;
|
|
870
|
-
}
|
|
871
|
-
});
|
|
872
|
-
Object.defineProperty(exports, "edgesOfFace", {
|
|
873
|
-
enumerable: true,
|
|
874
|
-
get: function() {
|
|
875
|
-
return edgesOfFace;
|
|
876
|
-
}
|
|
877
|
-
});
|
|
878
|
-
Object.defineProperty(exports, "ellipse", {
|
|
879
|
-
enumerable: true,
|
|
880
|
-
get: function() {
|
|
881
|
-
return ellipse;
|
|
882
|
-
}
|
|
883
|
-
});
|
|
884
|
-
Object.defineProperty(exports, "ellipseArc", {
|
|
885
|
-
enumerable: true,
|
|
886
|
-
get: function() {
|
|
887
|
-
return ellipseArc;
|
|
888
|
-
}
|
|
889
|
-
});
|
|
890
|
-
Object.defineProperty(exports, "ellipsoid", {
|
|
891
|
-
enumerable: true,
|
|
892
|
-
get: function() {
|
|
893
|
-
return ellipsoid;
|
|
894
|
-
}
|
|
895
|
-
});
|
|
896
|
-
Object.defineProperty(exports, "face", {
|
|
897
|
-
enumerable: true,
|
|
898
|
-
get: function() {
|
|
899
|
-
return face;
|
|
900
|
-
}
|
|
901
|
-
});
|
|
902
|
-
Object.defineProperty(exports, "facesOfEdge", {
|
|
903
|
-
enumerable: true,
|
|
904
|
-
get: function() {
|
|
905
|
-
return facesOfEdge;
|
|
906
|
-
}
|
|
907
|
-
});
|
|
908
|
-
Object.defineProperty(exports, "filledFace", {
|
|
909
|
-
enumerable: true,
|
|
910
|
-
get: function() {
|
|
911
|
-
return filledFace;
|
|
912
|
-
}
|
|
913
|
-
});
|
|
914
|
-
Object.defineProperty(exports, "heal", {
|
|
915
|
-
enumerable: true,
|
|
916
|
-
get: function() {
|
|
917
|
-
return heal;
|
|
918
|
-
}
|
|
919
|
-
});
|
|
920
|
-
Object.defineProperty(exports, "healFace", {
|
|
921
|
-
enumerable: true,
|
|
922
|
-
get: function() {
|
|
923
|
-
return healFace;
|
|
924
|
-
}
|
|
925
|
-
});
|
|
926
|
-
Object.defineProperty(exports, "healSolid", {
|
|
927
|
-
enumerable: true,
|
|
928
|
-
get: function() {
|
|
929
|
-
return healSolid;
|
|
930
|
-
}
|
|
931
|
-
});
|
|
932
|
-
Object.defineProperty(exports, "healWire", {
|
|
933
|
-
enumerable: true,
|
|
934
|
-
get: function() {
|
|
935
|
-
return healWire;
|
|
936
|
-
}
|
|
937
|
-
});
|
|
938
|
-
Object.defineProperty(exports, "helix", {
|
|
939
|
-
enumerable: true,
|
|
940
|
-
get: function() {
|
|
941
|
-
return helix;
|
|
942
|
-
}
|
|
943
|
-
});
|
|
944
|
-
Object.defineProperty(exports, "isValid", {
|
|
945
|
-
enumerable: true,
|
|
946
|
-
get: function() {
|
|
947
|
-
return isValid;
|
|
948
|
-
}
|
|
949
|
-
});
|
|
950
|
-
Object.defineProperty(exports, "line", {
|
|
951
|
-
enumerable: true,
|
|
952
|
-
get: function() {
|
|
953
|
-
return line;
|
|
954
|
-
}
|
|
955
|
-
});
|
|
956
|
-
Object.defineProperty(exports, "offsetFace", {
|
|
957
|
-
enumerable: true,
|
|
958
|
-
get: function() {
|
|
959
|
-
return offsetFace;
|
|
960
|
-
}
|
|
961
|
-
});
|
|
962
|
-
Object.defineProperty(exports, "polygon", {
|
|
963
|
-
enumerable: true,
|
|
964
|
-
get: function() {
|
|
965
|
-
return polygon;
|
|
966
|
-
}
|
|
967
|
-
});
|
|
968
|
-
Object.defineProperty(exports, "sewShells", {
|
|
969
|
-
enumerable: true,
|
|
970
|
-
get: function() {
|
|
971
|
-
return sewShells;
|
|
972
|
-
}
|
|
973
|
-
});
|
|
974
|
-
Object.defineProperty(exports, "sharedEdges", {
|
|
975
|
-
enumerable: true,
|
|
976
|
-
get: function() {
|
|
977
|
-
return sharedEdges;
|
|
978
|
-
}
|
|
979
|
-
});
|
|
980
|
-
Object.defineProperty(exports, "solid", {
|
|
981
|
-
enumerable: true,
|
|
982
|
-
get: function() {
|
|
983
|
-
return solid;
|
|
984
|
-
}
|
|
985
|
-
});
|
|
986
|
-
Object.defineProperty(exports, "sphere", {
|
|
987
|
-
enumerable: true,
|
|
988
|
-
get: function() {
|
|
989
|
-
return sphere;
|
|
990
|
-
}
|
|
991
|
-
});
|
|
992
|
-
Object.defineProperty(exports, "subFace", {
|
|
993
|
-
enumerable: true,
|
|
994
|
-
get: function() {
|
|
995
|
-
return subFace;
|
|
996
|
-
}
|
|
997
|
-
});
|
|
998
|
-
Object.defineProperty(exports, "tangentArc", {
|
|
999
|
-
enumerable: true,
|
|
1000
|
-
get: function() {
|
|
1001
|
-
return tangentArc;
|
|
1002
|
-
}
|
|
1003
|
-
});
|
|
1004
|
-
Object.defineProperty(exports, "threePointArc", {
|
|
1005
|
-
enumerable: true,
|
|
1006
|
-
get: function() {
|
|
1007
|
-
return threePointArc;
|
|
1008
|
-
}
|
|
1009
|
-
});
|
|
1010
|
-
Object.defineProperty(exports, "toBufferGeometryData", {
|
|
1011
|
-
enumerable: true,
|
|
1012
|
-
get: function() {
|
|
1013
|
-
return toBufferGeometryData;
|
|
1014
|
-
}
|
|
1015
|
-
});
|
|
1016
|
-
Object.defineProperty(exports, "toGroupedBufferGeometryData", {
|
|
1017
|
-
enumerable: true,
|
|
1018
|
-
get: function() {
|
|
1019
|
-
return toGroupedBufferGeometryData;
|
|
1020
|
-
}
|
|
1021
|
-
});
|
|
1022
|
-
Object.defineProperty(exports, "toLineGeometryData", {
|
|
1023
|
-
enumerable: true,
|
|
1024
|
-
get: function() {
|
|
1025
|
-
return toLineGeometryData;
|
|
1026
|
-
}
|
|
1027
|
-
});
|
|
1028
|
-
Object.defineProperty(exports, "torus", {
|
|
1029
|
-
enumerable: true,
|
|
1030
|
-
get: function() {
|
|
1031
|
-
return torus;
|
|
1032
|
-
}
|
|
1033
|
-
});
|
|
1034
|
-
Object.defineProperty(exports, "vertex", {
|
|
1035
|
-
enumerable: true,
|
|
1036
|
-
get: function() {
|
|
1037
|
-
return vertex;
|
|
1038
|
-
}
|
|
1039
|
-
});
|
|
1040
|
-
Object.defineProperty(exports, "verticesOfEdge", {
|
|
1041
|
-
enumerable: true,
|
|
1042
|
-
get: function() {
|
|
1043
|
-
return verticesOfEdge;
|
|
1044
|
-
}
|
|
1045
|
-
});
|
|
1046
|
-
Object.defineProperty(exports, "wire", {
|
|
1047
|
-
enumerable: true,
|
|
1048
|
-
get: function() {
|
|
1049
|
-
return wire;
|
|
1050
|
-
}
|
|
1051
|
-
});
|
|
1052
|
-
Object.defineProperty(exports, "wireLoop", {
|
|
1053
|
-
enumerable: true,
|
|
1054
|
-
get: function() {
|
|
1055
|
-
return wireLoop;
|
|
1056
|
-
}
|
|
1057
|
-
});
|
|
1058
|
-
Object.defineProperty(exports, "wiresOfFace", {
|
|
1059
|
-
enumerable: true,
|
|
1060
|
-
get: function() {
|
|
1061
|
-
return wiresOfFace;
|
|
1062
|
-
}
|
|
1063
|
-
});
|