brepjs 8.0.0 → 8.0.2
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/blueprints/booleanHelpers.d.ts +32 -0
- package/dist/2d/blueprints/booleanHelpers.d.ts.map +1 -0
- package/dist/2d/blueprints/booleanOperations.d.ts +5 -3
- package/dist/2d/blueprints/booleanOperations.d.ts.map +1 -1
- package/dist/2d/blueprints/intersectionSegments.d.ts +12 -0
- package/dist/2d/blueprints/intersectionSegments.d.ts.map +1 -0
- package/dist/2d/blueprints/segmentAssembly.d.ts +31 -0
- package/dist/2d/blueprints/segmentAssembly.d.ts.map +1 -0
- package/dist/2d.cjs +2 -2
- package/dist/2d.js +8 -8
- package/dist/{Blueprint-D3JfGJTz.js → Blueprint-B9fhnpFp.js} +117 -30
- package/dist/{Blueprint-CVctc41Z.cjs → Blueprint-VGbo3izk.cjs} +111 -24
- package/dist/{boolean2D-BdZATaHs.cjs → boolean2D-B1XrGVgx.cjs} +426 -345
- package/dist/{boolean2D-hOw5Qay5.js → boolean2D-_WiqPxWZ.js} +391 -310
- package/dist/{booleanFns-BBSVKhL2.cjs → booleanFns-BxW-N3rP.cjs} +12 -16
- package/dist/{booleanFns-CqehfzcK.js → booleanFns-CkccZ7UL.js} +14 -18
- package/dist/brepjs.cjs +133 -62
- package/dist/brepjs.js +290 -217
- package/dist/{cast-DQaUibmm.js → cast-C4Ff_1Qe.js} +2 -2
- package/dist/{cast-DkB0GKmQ.cjs → cast-DIiyxDLo.cjs} +2 -2
- package/dist/core/disposal.d.ts +1 -1
- package/dist/core/disposal.d.ts.map +1 -1
- package/dist/core.cjs +3 -3
- package/dist/core.js +3 -3
- package/dist/cornerFinder-BndBNtJE.cjs +58 -0
- package/dist/cornerFinder-DzGzfiqb.js +59 -0
- package/dist/curveBuilders-BUoFO1UG.cjs +196 -0
- package/dist/curveBuilders-CBlIWlbU.js +197 -0
- package/dist/{curveFns-BilyYL_s.cjs → curveFns-BrJDkaWi.cjs} +31 -44
- package/dist/{curveFns-CdVE4da7.js → curveFns-BshHA9Ys.js} +31 -44
- package/dist/{drawFns-921SkhDL.js → drawFns-Btmlh_Oz.js} +13 -14
- package/dist/{drawFns-CUyx50gi.cjs → drawFns-D2eDcf4k.cjs} +58 -59
- package/dist/{faceFns-DHu-2JpA.js → faceFns-DDzCECn3.js} +3 -3
- package/dist/{faceFns-BwK7FP7N.cjs → faceFns-NDRFeekj.cjs} +3 -3
- package/dist/helpers-Ck8GJ58k.cjs +203 -0
- package/dist/helpers-jku2V1DY.js +204 -0
- package/dist/io.cjs +4 -4
- package/dist/io.js +4 -4
- package/dist/kernel/occtAdapter.d.ts +1 -0
- package/dist/kernel/occtAdapter.d.ts.map +1 -1
- package/dist/kernel/sweepOps.d.ts +8 -0
- package/dist/kernel/sweepOps.d.ts.map +1 -1
- package/dist/kernel/types.d.ts +1 -0
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/loft-Bk9EM0gZ.js +373 -0
- package/dist/loft-DJXwxV_L.cjs +372 -0
- package/dist/{measurement-C5JGCuUP.js → measurement-DlXaTzKc.js} +3 -3
- package/dist/{measurement-fxm_pW7x.cjs → measurement-LcGh4wV0.cjs} +3 -3
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-AqAjTTVl.js → meshFns-Djzdn-CS.js} +1 -1
- package/dist/{meshFns-BhrZGi6w.cjs → meshFns-c8lDKfYy.cjs} +1 -1
- package/dist/{occtBoundary-du8_ex-p.cjs → occtBoundary-6kQSl3cF.cjs} +21 -0
- package/dist/{occtBoundary-CwegMzqc.js → occtBoundary-CqXvDhZY.js} +26 -5
- package/dist/operations/extrude.d.ts.map +1 -1
- package/dist/operations/extrudeFns.d.ts.map +1 -1
- package/dist/operations/extrudeUtils.d.ts +17 -0
- package/dist/operations/extrudeUtils.d.ts.map +1 -1
- package/dist/{operations-C1rWoba2.js → operations-CrQlFDHc.js} +30 -7
- package/dist/{operations-BP1wVDw0.cjs → operations-Do-WZGXc.cjs} +30 -7
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +4 -4
- package/dist/query/cornerFinder.d.ts +48 -0
- package/dist/query/cornerFinder.d.ts.map +1 -0
- package/dist/query/directionUtils.d.ts +6 -0
- package/dist/query/directionUtils.d.ts.map +1 -0
- package/dist/query/edgeFinder.d.ts +15 -0
- package/dist/query/edgeFinder.d.ts.map +1 -0
- package/dist/query/faceFinder.d.ts +15 -0
- package/dist/query/faceFinder.d.ts.map +1 -0
- package/dist/query/finderCore.d.ts +35 -0
- package/dist/query/finderCore.d.ts.map +1 -0
- package/dist/query/finderFns.d.ts +21 -106
- package/dist/query/finderFns.d.ts.map +1 -1
- package/dist/query/shapeDistanceFilter.d.ts +11 -0
- package/dist/query/shapeDistanceFilter.d.ts.map +1 -0
- package/dist/query/vertexFinder.d.ts +16 -0
- package/dist/query/vertexFinder.d.ts.map +1 -0
- package/dist/query/wireFinder.d.ts +10 -0
- package/dist/query/wireFinder.d.ts.map +1 -0
- package/dist/query.cjs +42 -5
- package/dist/query.js +40 -2
- package/dist/{shapeFns-BrF97sKt.js → shapeFns-DQtpzndX.js} +17 -18
- package/dist/{shapeFns-BvOndshS.cjs → shapeFns-cN4qGpbO.cjs} +6 -7
- package/dist/{shapeTypes-DKhwEnUM.cjs → shapeTypes-BJ3Hmskg.cjs} +24 -20
- package/dist/{shapeTypes-BlSElW8z.js → shapeTypes-C9sUsmEW.js} +32 -28
- package/dist/sketching/Sketcher.d.ts.map +1 -1
- package/dist/sketching/Sketcher2d.d.ts +12 -4
- package/dist/sketching/Sketcher2d.d.ts.map +1 -1
- package/dist/sketching/ellipseUtils.d.ts +29 -0
- package/dist/sketching/ellipseUtils.d.ts.map +1 -0
- package/dist/sketching.cjs +2 -2
- package/dist/sketching.js +2 -2
- package/dist/topology/booleanFns.d.ts.map +1 -1
- package/dist/topology/curveBuilders.d.ts +75 -0
- package/dist/topology/curveBuilders.d.ts.map +1 -0
- package/dist/topology/curveFns.d.ts.map +1 -1
- package/dist/topology/primitiveFns.d.ts.map +1 -1
- package/dist/topology/shapeFns.d.ts.map +1 -1
- package/dist/topology/shapeHelpers.d.ts +6 -173
- package/dist/topology/shapeHelpers.d.ts.map +1 -1
- package/dist/topology/shapeUtils.d.ts +13 -0
- package/dist/topology/shapeUtils.d.ts.map +1 -0
- package/dist/topology/solidBuilders.d.ts +70 -0
- package/dist/topology/solidBuilders.d.ts.map +1 -0
- package/dist/topology/surfaceBuilders.d.ts +35 -0
- package/dist/topology/surfaceBuilders.d.ts.map +1 -0
- package/dist/topology/wrapperFns.d.ts +1 -0
- package/dist/topology/wrapperFns.d.ts.map +1 -1
- package/dist/{topology-tFzqSrGH.js → topology-CtfUZwLR.js} +8 -8
- package/dist/{topology-CIooytHH.cjs → topology-DXq8dLsi.cjs} +8 -8
- package/dist/topology.cjs +7 -7
- package/dist/topology.js +31 -31
- package/dist/{vectors-CBuaMeZv.js → vectors-BVgXsYWl.js} +1 -1
- package/dist/{vectors-ChWEZPwy.cjs → vectors-DK2hEKcI.cjs} +1 -1
- package/dist/vectors.cjs +2 -2
- package/dist/vectors.js +2 -2
- package/package.json +1 -1
- package/dist/loft-BzWFokmC.cjs +0 -178
- package/dist/loft-CtG5nMq5.js +0 -179
- package/dist/query-V6nV-VfL.js +0 -396
- package/dist/query-hMSmOWJP.cjs +0 -395
- package/dist/shapeHelpers-B2SXz1p4.cjs +0 -488
- package/dist/shapeHelpers-BcoZf2N9.js +0 -489
package/dist/loft-CtG5nMq5.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { g as getKernel, a as toVec3, m as makeOcAx1 } from "./occtBoundary-CwegMzqc.js";
|
|
2
|
-
import { D as DEG2RAD, v as vecAdd, g as vecLength } from "./vecOps-ZDdZWbwT.js";
|
|
3
|
-
import { d as downcast, c as cast, a as isShape3D, b as isWire } from "./cast-DQaUibmm.js";
|
|
4
|
-
import { e as err, x as validationError, l as ok, u as unwrap, a as andThen, o as occtError, p as typeCastError } from "./errors-wGhcJMpB.js";
|
|
5
|
-
import { n as gcWithScope, o as localGC, p as createSolid } from "./shapeTypes-BlSElW8z.js";
|
|
6
|
-
import { m as makeLine, a as assembleWire, b as makeHelix, c as makeVertex } from "./shapeHelpers-BcoZf2N9.js";
|
|
7
|
-
function buildLawFromProfile(extrusionLength, { profile, endFactor = 1 }) {
|
|
8
|
-
const oc = getKernel().oc;
|
|
9
|
-
const r = gcWithScope();
|
|
10
|
-
let law;
|
|
11
|
-
if (profile === "s-curve") {
|
|
12
|
-
law = r(new oc.Law_S());
|
|
13
|
-
law.Set_1(0, 1, extrusionLength, endFactor);
|
|
14
|
-
} else if (profile === "linear") {
|
|
15
|
-
law = r(new oc.Law_Linear());
|
|
16
|
-
law.Set(0, 1, extrusionLength, endFactor);
|
|
17
|
-
} else {
|
|
18
|
-
return err(
|
|
19
|
-
validationError("UNSUPPORTED_PROFILE", `Unsupported extrusion profile: ${String(profile)}`)
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
return ok(law.Trim(0, extrusionLength, 1e-6));
|
|
23
|
-
}
|
|
24
|
-
const basicFaceExtrusion = (face, extrusionVec) => {
|
|
25
|
-
const oc = getKernel().oc;
|
|
26
|
-
const [r, gc] = localGC();
|
|
27
|
-
const vec = toVec3(extrusionVec);
|
|
28
|
-
const ocVec = r(new oc.gp_Vec_4(vec[0], vec[1], vec[2]));
|
|
29
|
-
const solidBuilder = r(new oc.BRepPrimAPI_MakePrism_1(face.wrapped, ocVec, false, true));
|
|
30
|
-
const solid = createSolid(unwrap(downcast(solidBuilder.Shape())));
|
|
31
|
-
gc();
|
|
32
|
-
return solid;
|
|
33
|
-
};
|
|
34
|
-
const revolution = (face, center = [0, 0, 0], direction = [0, 0, 1], angle = 360) => {
|
|
35
|
-
const oc = getKernel().oc;
|
|
36
|
-
const [r, gc] = localGC();
|
|
37
|
-
const centerVec = toVec3(center);
|
|
38
|
-
const directionVec = toVec3(direction);
|
|
39
|
-
const ax = r(makeOcAx1(centerVec, directionVec));
|
|
40
|
-
const revolBuilder = r(new oc.BRepPrimAPI_MakeRevol_1(face.wrapped, ax, angle * DEG2RAD, false));
|
|
41
|
-
const result = andThen(cast(revolBuilder.Shape()), (shape) => {
|
|
42
|
-
if (!isShape3D(shape))
|
|
43
|
-
return err(typeCastError("REVOLUTION_NOT_3D", "Revolution did not produce a 3D shape"));
|
|
44
|
-
return ok(shape);
|
|
45
|
-
});
|
|
46
|
-
gc();
|
|
47
|
-
return result;
|
|
48
|
-
};
|
|
49
|
-
function genericSweep(wire, spine, {
|
|
50
|
-
frenet = false,
|
|
51
|
-
auxiliarySpine,
|
|
52
|
-
law = null,
|
|
53
|
-
transitionMode = "right",
|
|
54
|
-
withContact,
|
|
55
|
-
support,
|
|
56
|
-
forceProfileSpineOthogonality
|
|
57
|
-
} = {}, shellMode = false) {
|
|
58
|
-
const oc = getKernel().oc;
|
|
59
|
-
const [r, gc] = localGC();
|
|
60
|
-
const withCorrection = transitionMode === "round" ? true : !!forceProfileSpineOthogonality;
|
|
61
|
-
const sweepBuilder = r(new oc.BRepOffsetAPI_MakePipeShell(spine.wrapped));
|
|
62
|
-
{
|
|
63
|
-
const mode = {
|
|
64
|
-
transformed: oc.BRepBuilderAPI_TransitionMode.BRepBuilderAPI_Transformed,
|
|
65
|
-
round: oc.BRepBuilderAPI_TransitionMode.BRepBuilderAPI_RoundCorner,
|
|
66
|
-
right: oc.BRepBuilderAPI_TransitionMode.BRepBuilderAPI_RightCorner
|
|
67
|
-
}[transitionMode];
|
|
68
|
-
if (mode) sweepBuilder.SetTransitionMode(mode);
|
|
69
|
-
}
|
|
70
|
-
if (support) {
|
|
71
|
-
sweepBuilder.SetMode_4(support);
|
|
72
|
-
} else if (frenet) {
|
|
73
|
-
sweepBuilder.SetMode_1(frenet);
|
|
74
|
-
}
|
|
75
|
-
if (auxiliarySpine) {
|
|
76
|
-
sweepBuilder.SetMode_5(
|
|
77
|
-
auxiliarySpine.wrapped,
|
|
78
|
-
false,
|
|
79
|
-
oc.BRepFill_TypeOfContact.BRepFill_NoContact
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
if (!law) sweepBuilder.Add_1(wire.wrapped, !!withContact, withCorrection);
|
|
83
|
-
else sweepBuilder.SetLaw_1(wire.wrapped, law, !!withContact, withCorrection);
|
|
84
|
-
const progress = r(new oc.Message_ProgressRange_1());
|
|
85
|
-
sweepBuilder.Build(progress);
|
|
86
|
-
if (!sweepBuilder.IsDone()) {
|
|
87
|
-
gc();
|
|
88
|
-
return err(occtError("SWEEP_FAILED", "Sweep operation failed"));
|
|
89
|
-
}
|
|
90
|
-
if (!shellMode) {
|
|
91
|
-
sweepBuilder.MakeSolid();
|
|
92
|
-
}
|
|
93
|
-
const shape = unwrap(cast(sweepBuilder.Shape()));
|
|
94
|
-
if (!isShape3D(shape)) {
|
|
95
|
-
gc();
|
|
96
|
-
return err(typeCastError("SWEEP_NOT_3D", "Sweep did not produce a 3D shape"));
|
|
97
|
-
}
|
|
98
|
-
if (shellMode) {
|
|
99
|
-
const startWire = unwrap(cast(sweepBuilder.FirstShape()));
|
|
100
|
-
const endWire = unwrap(cast(sweepBuilder.LastShape()));
|
|
101
|
-
if (!isWire(startWire)) {
|
|
102
|
-
gc();
|
|
103
|
-
return err(typeCastError("SWEEP_START_NOT_WIRE", "Sweep did not produce a start Wire"));
|
|
104
|
-
}
|
|
105
|
-
if (!isWire(endWire)) {
|
|
106
|
-
gc();
|
|
107
|
-
return err(typeCastError("SWEEP_END_NOT_WIRE", "Sweep did not produce an end Wire"));
|
|
108
|
-
}
|
|
109
|
-
gc();
|
|
110
|
-
return ok([shape, startWire, endWire]);
|
|
111
|
-
}
|
|
112
|
-
gc();
|
|
113
|
-
return ok(shape);
|
|
114
|
-
}
|
|
115
|
-
function complexExtrude(wire, center, normal, profileShape, shellMode = false) {
|
|
116
|
-
const [r, gc] = localGC();
|
|
117
|
-
const centerVec = toVec3(center);
|
|
118
|
-
const normalVec = toVec3(normal);
|
|
119
|
-
const endVec = vecAdd(centerVec, normalVec);
|
|
120
|
-
const mainSpineEdge = r(makeLine(centerVec, endVec));
|
|
121
|
-
const spine = r(unwrap(assembleWire([mainSpineEdge])));
|
|
122
|
-
const law = profileShape ? r(unwrap(buildLawFromProfile(vecLength(normalVec), profileShape))) : null;
|
|
123
|
-
const result = shellMode ? genericSweep(wire, spine, { law }, shellMode) : genericSweep(wire, spine, { law }, shellMode);
|
|
124
|
-
gc();
|
|
125
|
-
return result;
|
|
126
|
-
}
|
|
127
|
-
function twistExtrude(wire, angleDegrees, center, normal, profileShape, shellMode = false) {
|
|
128
|
-
const [r, gc] = localGC();
|
|
129
|
-
const centerVec = toVec3(center);
|
|
130
|
-
const normalVec = toVec3(normal);
|
|
131
|
-
const endVec = vecAdd(centerVec, normalVec);
|
|
132
|
-
const mainSpineEdge = r(makeLine(centerVec, endVec));
|
|
133
|
-
const spine = r(unwrap(assembleWire([mainSpineEdge])));
|
|
134
|
-
const extrusionLength = vecLength(normalVec);
|
|
135
|
-
const pitch = 360 / angleDegrees * extrusionLength;
|
|
136
|
-
const radius = 1;
|
|
137
|
-
const auxiliarySpine = r(makeHelix(pitch, extrusionLength, radius, centerVec, normalVec));
|
|
138
|
-
const law = profileShape ? r(unwrap(buildLawFromProfile(extrusionLength, profileShape))) : null;
|
|
139
|
-
const result = shellMode ? genericSweep(wire, spine, { auxiliarySpine, law }, shellMode) : genericSweep(wire, spine, { auxiliarySpine, law }, shellMode);
|
|
140
|
-
gc();
|
|
141
|
-
return result;
|
|
142
|
-
}
|
|
143
|
-
const loft = (wires, { ruled = true, startPoint, endPoint } = {}, returnShell = false) => {
|
|
144
|
-
if (wires.length === 0 && !startPoint && !endPoint) {
|
|
145
|
-
return err(validationError("LOFT_EMPTY", "Loft requires at least one wire or start/end point"));
|
|
146
|
-
}
|
|
147
|
-
const oc = getKernel().oc;
|
|
148
|
-
const [r, gc] = localGC();
|
|
149
|
-
const loftBuilder = r(new oc.BRepOffsetAPI_ThruSections(!returnShell, ruled, 1e-6));
|
|
150
|
-
if (startPoint) {
|
|
151
|
-
loftBuilder.AddVertex(r(makeVertex(toVec3(startPoint))).wrapped);
|
|
152
|
-
}
|
|
153
|
-
wires.forEach((w) => loftBuilder.AddWire(w.wrapped));
|
|
154
|
-
if (endPoint) {
|
|
155
|
-
loftBuilder.AddVertex(r(makeVertex(toVec3(endPoint))).wrapped);
|
|
156
|
-
}
|
|
157
|
-
const progress = r(new oc.Message_ProgressRange_1());
|
|
158
|
-
loftBuilder.Build(progress);
|
|
159
|
-
if (!loftBuilder.IsDone()) {
|
|
160
|
-
gc();
|
|
161
|
-
return err(occtError("LOFT_FAILED", "Loft operation failed"));
|
|
162
|
-
}
|
|
163
|
-
const result = andThen(cast(loftBuilder.Shape()), (shape) => {
|
|
164
|
-
if (!isShape3D(shape))
|
|
165
|
-
return err(typeCastError("LOFT_NOT_3D", "Loft did not produce a 3D shape"));
|
|
166
|
-
return ok(shape);
|
|
167
|
-
});
|
|
168
|
-
gc();
|
|
169
|
-
return result;
|
|
170
|
-
};
|
|
171
|
-
export {
|
|
172
|
-
buildLawFromProfile as a,
|
|
173
|
-
basicFaceExtrusion as b,
|
|
174
|
-
complexExtrude as c,
|
|
175
|
-
genericSweep as g,
|
|
176
|
-
loft as l,
|
|
177
|
-
revolution as r,
|
|
178
|
-
twistExtrude as t
|
|
179
|
-
};
|
package/dist/query-V6nV-VfL.js
DELETED
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
import { g as getKernel, d as toOcPnt } from "./occtBoundary-CwegMzqc.js";
|
|
2
|
-
import { c as castShape, n as gcWithScope, e as isFace } from "./shapeTypes-BlSElW8z.js";
|
|
3
|
-
import { j as vecNormalize, c as vecDistance, d as vecDot, D as DEG2RAD } from "./vecOps-ZDdZWbwT.js";
|
|
4
|
-
import { bug } from "./result.js";
|
|
5
|
-
import { i as iterTopo, d as downcast } from "./cast-DQaUibmm.js";
|
|
6
|
-
import { v as vertexPosition, k as getHashCode, n as isSameShape } from "./shapeFns-BrF97sKt.js";
|
|
7
|
-
import { g as getSurfaceType, n as normalAt } from "./faceFns-DHu-2JpA.js";
|
|
8
|
-
import { m as measureArea } from "./measurement-C5JGCuUP.js";
|
|
9
|
-
import { l as getCurveType, f as curveLength, c as curveIsClosed } from "./curveFns-CdVE4da7.js";
|
|
10
|
-
import { e as err, q as queryError, l as ok, u as unwrap } from "./errors-wGhcJMpB.js";
|
|
11
|
-
const PRECISION_INTERSECTION = 1e-9;
|
|
12
|
-
const PRECISION_OFFSET = 1e-8;
|
|
13
|
-
const PRECISION_POINT = 1e-6;
|
|
14
|
-
const samePoint = ([x0, y0], [x1, y1], precision = PRECISION_POINT) => {
|
|
15
|
-
return Math.abs(x0 - x1) <= precision && Math.abs(y0 - y1) <= precision;
|
|
16
|
-
};
|
|
17
|
-
const add2d = ([x0, y0], [x1, y1]) => {
|
|
18
|
-
return [x0 + x1, y0 + y1];
|
|
19
|
-
};
|
|
20
|
-
const subtract2d = ([x0, y0], [x1, y1]) => {
|
|
21
|
-
return [x0 - x1, y0 - y1];
|
|
22
|
-
};
|
|
23
|
-
const scalarMultiply2d = ([x0, y0], scalar) => {
|
|
24
|
-
return [x0 * scalar, y0 * scalar];
|
|
25
|
-
};
|
|
26
|
-
const distance2d = ([x0, y0], [x1, y1] = [0, 0]) => {
|
|
27
|
-
return Math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2);
|
|
28
|
-
};
|
|
29
|
-
const squareDistance2d = ([x0, y0], [x1, y1] = [0, 0]) => {
|
|
30
|
-
return (x0 - x1) ** 2 + (y0 - y1) ** 2;
|
|
31
|
-
};
|
|
32
|
-
function crossProduct2d([x0, y0], [x1, y1]) {
|
|
33
|
-
return x0 * y1 - y0 * x1;
|
|
34
|
-
}
|
|
35
|
-
const angle2d = ([x0, y0], [x1, y1] = [0, 0]) => {
|
|
36
|
-
return Math.atan2(y1 * x0 - y0 * x1, x0 * x1 + y0 * y1);
|
|
37
|
-
};
|
|
38
|
-
const polarAngle2d = ([x0, y0], [x1, y1] = [0, 0]) => {
|
|
39
|
-
return Math.atan2(y1 - y0, x1 - x0);
|
|
40
|
-
};
|
|
41
|
-
const normalize2d = ([x0, y0]) => {
|
|
42
|
-
const l = distance2d([x0, y0]);
|
|
43
|
-
if (l < 1e-12) {
|
|
44
|
-
bug("normalize2d", "Cannot normalize zero-length vector");
|
|
45
|
-
}
|
|
46
|
-
return [x0 / l, y0 / l];
|
|
47
|
-
};
|
|
48
|
-
const rotate2d = (point, angle, center = [0, 0]) => {
|
|
49
|
-
const [px0, py0] = point;
|
|
50
|
-
const [cx, cy] = center;
|
|
51
|
-
const px = px0 - cx;
|
|
52
|
-
const py = py0 - cy;
|
|
53
|
-
const sinA = Math.sin(angle);
|
|
54
|
-
const cosA = Math.cos(angle);
|
|
55
|
-
const xnew = px * cosA - py * sinA;
|
|
56
|
-
const ynew = px * sinA + py * cosA;
|
|
57
|
-
return [xnew + cx, ynew + cy];
|
|
58
|
-
};
|
|
59
|
-
const polarToCartesian = (r, theta) => {
|
|
60
|
-
const x = Math.cos(theta) * r;
|
|
61
|
-
const y = Math.sin(theta) * r;
|
|
62
|
-
return [x, y];
|
|
63
|
-
};
|
|
64
|
-
const cartesianToPolar = ([x, y]) => {
|
|
65
|
-
const r = distance2d([x, y]);
|
|
66
|
-
const theta = Math.atan2(y, x);
|
|
67
|
-
return [r, theta];
|
|
68
|
-
};
|
|
69
|
-
function createFinder(topoKind, filters, getNormal) {
|
|
70
|
-
const withFilter = (pred) => createFinder(topoKind, [...filters, pred]);
|
|
71
|
-
const shouldKeep = (element) => filters.every((f) => f(element));
|
|
72
|
-
const extractElements = (shape) => {
|
|
73
|
-
const result = [];
|
|
74
|
-
for (const raw of iterTopo(shape.wrapped, topoKind)) {
|
|
75
|
-
const element = castShape(unwrap(downcast(raw)));
|
|
76
|
-
if (shouldKeep(element)) {
|
|
77
|
-
result.push(element);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return result;
|
|
81
|
-
};
|
|
82
|
-
const finder = {
|
|
83
|
-
_filters: filters,
|
|
84
|
-
_topoKind: topoKind,
|
|
85
|
-
when: (pred) => withFilter(pred),
|
|
86
|
-
inList: (elements) => {
|
|
87
|
-
const hashSet = /* @__PURE__ */ new Map();
|
|
88
|
-
for (const e of elements) {
|
|
89
|
-
const h = getHashCode(e);
|
|
90
|
-
const bucket = hashSet.get(h);
|
|
91
|
-
if (bucket) bucket.push(e);
|
|
92
|
-
else hashSet.set(h, [e]);
|
|
93
|
-
}
|
|
94
|
-
return withFilter((el) => {
|
|
95
|
-
const bucket = hashSet.get(getHashCode(el));
|
|
96
|
-
return !!bucket && bucket.some((e) => isSameShape(e, el));
|
|
97
|
-
});
|
|
98
|
-
},
|
|
99
|
-
not: (builderFn) => {
|
|
100
|
-
const inner = builderFn(createFinder(topoKind, []));
|
|
101
|
-
return withFilter((el) => !inner.shouldKeep(el));
|
|
102
|
-
},
|
|
103
|
-
either: (fns) => {
|
|
104
|
-
const builtFinders = fns.map((fn) => fn(createFinder(topoKind, [])));
|
|
105
|
-
return withFilter((el) => builtFinders.some((f) => f.shouldKeep(el)));
|
|
106
|
-
},
|
|
107
|
-
findAll: (shape) => extractElements(shape),
|
|
108
|
-
findUnique: (shape) => {
|
|
109
|
-
const elements = extractElements(shape);
|
|
110
|
-
if (elements.length !== 1) {
|
|
111
|
-
return err(
|
|
112
|
-
queryError(
|
|
113
|
-
"FINDER_NOT_UNIQUE",
|
|
114
|
-
`Finder expected a unique match but found ${elements.length} element(s)`
|
|
115
|
-
)
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
return ok(elements[0]);
|
|
119
|
-
},
|
|
120
|
-
shouldKeep
|
|
121
|
-
};
|
|
122
|
-
return finder;
|
|
123
|
-
}
|
|
124
|
-
const DIRECTIONS = {
|
|
125
|
-
X: [1, 0, 0],
|
|
126
|
-
Y: [0, 1, 0],
|
|
127
|
-
Z: [0, 0, 1]
|
|
128
|
-
};
|
|
129
|
-
function resolveDir(dir) {
|
|
130
|
-
if (typeof dir === "string") return DIRECTIONS[dir] ?? [0, 0, 1];
|
|
131
|
-
return dir;
|
|
132
|
-
}
|
|
133
|
-
function edgeFinder() {
|
|
134
|
-
return createEdgeFinder([]);
|
|
135
|
-
}
|
|
136
|
-
function createEdgeFinder(filters) {
|
|
137
|
-
const base = createFinder("edge", filters);
|
|
138
|
-
const withFilter = (pred) => createEdgeFinder([...filters, pred]);
|
|
139
|
-
return {
|
|
140
|
-
...base,
|
|
141
|
-
when: (pred) => createEdgeFinder([...filters, pred]),
|
|
142
|
-
inList: (elements) => createEdgeFinder([...base.inList(elements)._filters]),
|
|
143
|
-
not: (fn) => createEdgeFinder([...base.not(fn)._filters]),
|
|
144
|
-
either: (fns) => createEdgeFinder([
|
|
145
|
-
...base.either(fns)._filters
|
|
146
|
-
]),
|
|
147
|
-
inDirection: (dir = "Z", angle = 0) => {
|
|
148
|
-
const d = vecNormalize(resolveDir(dir));
|
|
149
|
-
return withFilter((edge) => {
|
|
150
|
-
const oc = getKernel().oc;
|
|
151
|
-
const r = gcWithScope();
|
|
152
|
-
const adaptor = r(new oc.BRepAdaptor_Curve_2(edge.wrapped));
|
|
153
|
-
const tmpPnt = r(new oc.gp_Pnt_1());
|
|
154
|
-
const tmpVec = r(new oc.gp_Vec_1());
|
|
155
|
-
const mid = (Number(adaptor.FirstParameter()) + Number(adaptor.LastParameter())) / 2;
|
|
156
|
-
adaptor.D1(mid, tmpPnt, tmpVec);
|
|
157
|
-
const tangent = vecNormalize([tmpVec.X(), tmpVec.Y(), tmpVec.Z()]);
|
|
158
|
-
const ang = Math.acos(Math.min(1, Math.abs(vecDot(tangent, d))));
|
|
159
|
-
return Math.abs(ang - DEG2RAD * angle) < 1e-6;
|
|
160
|
-
});
|
|
161
|
-
},
|
|
162
|
-
ofLength: (length, tolerance = 1e-3) => withFilter((edge) => Math.abs(curveLength(edge) - length) < tolerance),
|
|
163
|
-
ofCurveType: (curveType) => withFilter((edge) => getCurveType(edge) === curveType),
|
|
164
|
-
parallelTo: (dir = "Z") => createEdgeFinder([...filters]).inDirection(dir, 0),
|
|
165
|
-
atDistance: (distance, point = [0, 0, 0]) => withFilter((edge) => {
|
|
166
|
-
const oc = getKernel().oc;
|
|
167
|
-
const r = gcWithScope();
|
|
168
|
-
const pnt = r(toOcPnt(point));
|
|
169
|
-
const vtxMaker = r(new oc.BRepBuilderAPI_MakeVertex(pnt));
|
|
170
|
-
const vtx = vtxMaker.Vertex();
|
|
171
|
-
const distTool = r(new oc.BRepExtrema_DistShapeShape_1());
|
|
172
|
-
distTool.LoadS1(vtx);
|
|
173
|
-
distTool.LoadS2(edge.wrapped);
|
|
174
|
-
const progress = r(new oc.Message_ProgressRange_1());
|
|
175
|
-
distTool.Perform(progress);
|
|
176
|
-
const d = distTool.Value();
|
|
177
|
-
return Math.abs(d - distance) < 1e-6;
|
|
178
|
-
})
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
function faceFinder() {
|
|
182
|
-
return createFaceFinder([]);
|
|
183
|
-
}
|
|
184
|
-
function createFaceFinder(filters) {
|
|
185
|
-
const base = createFinder("face", filters);
|
|
186
|
-
const withFilter = (pred) => createFaceFinder([...filters, pred]);
|
|
187
|
-
return {
|
|
188
|
-
...base,
|
|
189
|
-
when: (pred) => createFaceFinder([...filters, pred]),
|
|
190
|
-
inList: (elements) => createFaceFinder([...base.inList(elements)._filters]),
|
|
191
|
-
not: (fn) => createFaceFinder([...base.not(fn)._filters]),
|
|
192
|
-
either: (fns) => createFaceFinder([
|
|
193
|
-
...base.either(fns)._filters
|
|
194
|
-
]),
|
|
195
|
-
inDirection: (dir = "Z", angle = 0) => {
|
|
196
|
-
const d = vecNormalize(resolveDir(dir));
|
|
197
|
-
return withFilter((face) => {
|
|
198
|
-
const n = normalAt(face);
|
|
199
|
-
const ang = Math.acos(Math.min(1, Math.abs(vecDot(vecNormalize(n), d))));
|
|
200
|
-
return Math.abs(ang - DEG2RAD * angle) < 1e-6;
|
|
201
|
-
});
|
|
202
|
-
},
|
|
203
|
-
parallelTo: (dir = "Z") => createFaceFinder([...filters]).inDirection(dir, 0),
|
|
204
|
-
ofSurfaceType: (surfaceType) => withFilter((face) => unwrap(getSurfaceType(face)) === surfaceType),
|
|
205
|
-
ofArea: (area, tolerance = 1e-3) => withFilter((face) => Math.abs(measureArea(face) - area) < tolerance),
|
|
206
|
-
atDistance: (distance, point = [0, 0, 0]) => withFilter((face) => {
|
|
207
|
-
const oc = getKernel().oc;
|
|
208
|
-
const r = gcWithScope();
|
|
209
|
-
const pnt = r(toOcPnt(point));
|
|
210
|
-
const vtxMaker = r(new oc.BRepBuilderAPI_MakeVertex(pnt));
|
|
211
|
-
const vtx = vtxMaker.Vertex();
|
|
212
|
-
const distTool = r(new oc.BRepExtrema_DistShapeShape_1());
|
|
213
|
-
distTool.LoadS1(vtx);
|
|
214
|
-
distTool.LoadS2(face.wrapped);
|
|
215
|
-
const progress = r(new oc.Message_ProgressRange_1());
|
|
216
|
-
distTool.Perform(progress);
|
|
217
|
-
const d = distTool.Value();
|
|
218
|
-
return Math.abs(d - distance) < 1e-6;
|
|
219
|
-
})
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
function wireFinder() {
|
|
223
|
-
return createWireFinder([]);
|
|
224
|
-
}
|
|
225
|
-
function createWireFinder(filters) {
|
|
226
|
-
const base = createFinder("wire", filters);
|
|
227
|
-
const withFilter = (pred) => createWireFinder([...filters, pred]);
|
|
228
|
-
return {
|
|
229
|
-
...base,
|
|
230
|
-
when: (pred) => createWireFinder([...filters, pred]),
|
|
231
|
-
inList: (elements) => createWireFinder([...base.inList(elements)._filters]),
|
|
232
|
-
not: (fn) => createWireFinder([...base.not(fn)._filters]),
|
|
233
|
-
either: (fns) => createWireFinder([
|
|
234
|
-
...base.either(fns)._filters
|
|
235
|
-
]),
|
|
236
|
-
isClosed: () => withFilter((wire) => curveIsClosed(wire)),
|
|
237
|
-
isOpen: () => withFilter((wire) => !curveIsClosed(wire)),
|
|
238
|
-
ofEdgeCount: (count) => withFilter((wire) => {
|
|
239
|
-
let edgeCount = 0;
|
|
240
|
-
for (const _raw of iterTopo(wire.wrapped, "edge")) {
|
|
241
|
-
edgeCount++;
|
|
242
|
-
}
|
|
243
|
-
return edgeCount === count;
|
|
244
|
-
})
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
function vertexFinder() {
|
|
248
|
-
return createVertexFinder([]);
|
|
249
|
-
}
|
|
250
|
-
function createVertexFinder(filters) {
|
|
251
|
-
const base = createFinder("vertex", filters);
|
|
252
|
-
const withFilter = (pred) => createVertexFinder([...filters, pred]);
|
|
253
|
-
return {
|
|
254
|
-
...base,
|
|
255
|
-
when: (pred) => createVertexFinder([...filters, pred]),
|
|
256
|
-
inList: (elements) => createVertexFinder([...base.inList(elements)._filters]),
|
|
257
|
-
not: (fn) => createVertexFinder([
|
|
258
|
-
...base.not(fn)._filters
|
|
259
|
-
]),
|
|
260
|
-
either: (fns) => createVertexFinder([
|
|
261
|
-
...base.either(fns)._filters
|
|
262
|
-
]),
|
|
263
|
-
nearestTo: (point) => {
|
|
264
|
-
const newFilters = [...filters];
|
|
265
|
-
const finderWithNearestTo = createVertexFinderWithNearest(newFilters, point);
|
|
266
|
-
return finderWithNearestTo;
|
|
267
|
-
},
|
|
268
|
-
atPosition: (point, tolerance = 1e-4) => withFilter((vertex) => {
|
|
269
|
-
const pos = vertexPosition(vertex);
|
|
270
|
-
return vecDistance(pos, point) < tolerance;
|
|
271
|
-
}),
|
|
272
|
-
withinBox: (min, max) => withFilter((vertex) => {
|
|
273
|
-
const pos = vertexPosition(vertex);
|
|
274
|
-
return pos[0] >= min[0] - 1e-6 && pos[0] <= max[0] + 1e-6 && pos[1] >= min[1] - 1e-6 && pos[1] <= max[1] + 1e-6 && pos[2] >= min[2] - 1e-6 && pos[2] <= max[2] + 1e-6;
|
|
275
|
-
}),
|
|
276
|
-
atDistance: (distance, point = [0, 0, 0], tolerance = 1e-4) => withFilter((vertex) => {
|
|
277
|
-
const pos = vertexPosition(vertex);
|
|
278
|
-
return Math.abs(vecDistance(pos, point) - distance) < tolerance;
|
|
279
|
-
})
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
function createVertexFinderWithNearest(filters, nearestPoint) {
|
|
283
|
-
const baseFinder = createVertexFinder(filters);
|
|
284
|
-
const findAllNearest = (shape) => {
|
|
285
|
-
const candidates = baseFinder.findAll(shape);
|
|
286
|
-
if (candidates.length === 0) return [];
|
|
287
|
-
let bestIdx = 0;
|
|
288
|
-
let bestDist = vecDistance(vertexPosition(candidates[0]), nearestPoint);
|
|
289
|
-
for (let i = 1; i < candidates.length; i++) {
|
|
290
|
-
const d = vecDistance(vertexPosition(candidates[i]), nearestPoint);
|
|
291
|
-
if (d < bestDist) {
|
|
292
|
-
bestDist = d;
|
|
293
|
-
bestIdx = i;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return [candidates[bestIdx]];
|
|
297
|
-
};
|
|
298
|
-
const findUniqueNearest = (shape) => {
|
|
299
|
-
const nearest = findAllNearest(shape);
|
|
300
|
-
if (nearest.length === 0) {
|
|
301
|
-
return err(
|
|
302
|
-
queryError("FINDER_NOT_UNIQUE", "Finder expected a unique match but found 0 element(s)")
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
return ok(nearest[0]);
|
|
306
|
-
};
|
|
307
|
-
return {
|
|
308
|
-
...baseFinder,
|
|
309
|
-
findAll: findAllNearest,
|
|
310
|
-
findUnique: findUniqueNearest
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
const PI_2 = 2 * Math.PI;
|
|
314
|
-
const positiveHalfAngle = (angle) => {
|
|
315
|
-
const limitedAngle = angle % PI_2;
|
|
316
|
-
const coterminalAngle = limitedAngle < 0 ? limitedAngle + PI_2 : limitedAngle;
|
|
317
|
-
if (coterminalAngle < Math.PI) return coterminalAngle;
|
|
318
|
-
if (coterminalAngle === Math.PI) return 0;
|
|
319
|
-
return Math.abs(coterminalAngle - PI_2);
|
|
320
|
-
};
|
|
321
|
-
function blueprintCorners(blueprint) {
|
|
322
|
-
return blueprint.curves.map((curve, index) => ({
|
|
323
|
-
firstCurve: curve,
|
|
324
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
325
|
-
secondCurve: blueprint.curves[(index + 1) % blueprint.curves.length],
|
|
326
|
-
point: curve.lastPoint
|
|
327
|
-
}));
|
|
328
|
-
}
|
|
329
|
-
function cornerFinder() {
|
|
330
|
-
return createCornerFinder([]);
|
|
331
|
-
}
|
|
332
|
-
function createCornerFinder(filters) {
|
|
333
|
-
const withFilter = (pred) => createCornerFinder([...filters, pred]);
|
|
334
|
-
const shouldKeep = (corner) => filters.every((f) => f(corner));
|
|
335
|
-
return {
|
|
336
|
-
shouldKeep,
|
|
337
|
-
when: (pred) => withFilter(pred),
|
|
338
|
-
inList: (points) => withFilter((corner) => points.some((p) => samePoint(p, corner.point))),
|
|
339
|
-
atDistance: (distance, point = [0, 0]) => withFilter((corner) => Math.abs(distance2d(point, corner.point) - distance) < 1e-9),
|
|
340
|
-
atPoint: (point) => withFilter((corner) => samePoint(point, corner.point)),
|
|
341
|
-
inBox: (corner1, corner2) => {
|
|
342
|
-
const minX = Math.min(corner1[0], corner2[0]);
|
|
343
|
-
const maxX = Math.max(corner1[0], corner2[0]);
|
|
344
|
-
const minY = Math.min(corner1[1], corner2[1]);
|
|
345
|
-
const maxY = Math.max(corner1[1], corner2[1]);
|
|
346
|
-
return withFilter((corner) => {
|
|
347
|
-
const [x, y] = corner.point;
|
|
348
|
-
return x >= minX && x <= maxX && y >= minY && y <= maxY;
|
|
349
|
-
});
|
|
350
|
-
},
|
|
351
|
-
ofAngle: (angle) => withFilter((corner) => {
|
|
352
|
-
const tgt1 = corner.firstCurve.tangentAt(1);
|
|
353
|
-
const tgt2 = corner.secondCurve.tangentAt(0);
|
|
354
|
-
return Math.abs(positiveHalfAngle(angle2d(tgt1, tgt2)) - positiveHalfAngle(DEG2RAD * angle)) < 1e-9;
|
|
355
|
-
}),
|
|
356
|
-
not: (fn) => {
|
|
357
|
-
const inner = fn(createCornerFinder([]));
|
|
358
|
-
return withFilter((corner) => !inner.shouldKeep(corner));
|
|
359
|
-
},
|
|
360
|
-
either: (fns) => {
|
|
361
|
-
const builtFinders = fns.map((fn) => fn(createCornerFinder([])));
|
|
362
|
-
return withFilter((corner) => builtFinders.some((f) => f.shouldKeep(corner)));
|
|
363
|
-
},
|
|
364
|
-
find: (blueprint) => blueprintCorners(blueprint).filter(shouldKeep)
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
function getSingleFace(f, shape) {
|
|
368
|
-
if (typeof f === "object" && "_topoKind" in f) {
|
|
369
|
-
return f.findUnique(shape);
|
|
370
|
-
}
|
|
371
|
-
if (typeof f !== "function" && isFace(f)) return ok(f);
|
|
372
|
-
const fnResult = f(faceFinder());
|
|
373
|
-
return fnResult.findUnique(shape);
|
|
374
|
-
}
|
|
375
|
-
export {
|
|
376
|
-
PRECISION_INTERSECTION as P,
|
|
377
|
-
subtract2d as a,
|
|
378
|
-
add2d as b,
|
|
379
|
-
cornerFinder as c,
|
|
380
|
-
crossProduct2d as d,
|
|
381
|
-
edgeFinder as e,
|
|
382
|
-
faceFinder as f,
|
|
383
|
-
getSingleFace as g,
|
|
384
|
-
scalarMultiply2d as h,
|
|
385
|
-
distance2d as i,
|
|
386
|
-
cartesianToPolar as j,
|
|
387
|
-
polarAngle2d as k,
|
|
388
|
-
PRECISION_OFFSET as l,
|
|
389
|
-
squareDistance2d as m,
|
|
390
|
-
normalize2d as n,
|
|
391
|
-
polarToCartesian as p,
|
|
392
|
-
rotate2d as r,
|
|
393
|
-
samePoint as s,
|
|
394
|
-
vertexFinder as v,
|
|
395
|
-
wireFinder as w
|
|
396
|
-
};
|