brepjs 8.4.0 → 8.7.4
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 +2 -2
- package/dist/2d.js +13 -13
- package/dist/{Blueprint-zgFe_5Qj.cjs → Blueprint-BcbOBF-9.cjs} +11 -99
- package/dist/{Blueprint-Bp45tnh0.js → Blueprint-Cmh8lKc4.js} +29 -117
- package/dist/{boolean2D-CfEbRMPF.cjs → boolean2D-CqacqjME.cjs} +24 -25
- package/dist/{boolean2D-DN6ETTCq.js → boolean2D-D94Axs3i.js} +23 -24
- package/dist/{booleanFns-C-M6qqvB.js → booleanFns-DdjtpcM6.js} +306 -12
- package/dist/{booleanFns-5dDG0jpA.cjs → booleanFns-NtKxkiXn.cjs} +299 -5
- package/dist/brepjs.cjs +1619 -71
- package/dist/brepjs.js +1880 -333
- package/dist/core/errors.d.ts +18 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core.cjs +4 -4
- package/dist/core.js +4 -4
- package/dist/{cornerFinder-CC_MunIh.js → cornerFinder-BBOYfsXl.js} +1 -1
- package/dist/{cornerFinder-BQ-_VJx0.cjs → cornerFinder-Bqy8Lw2p.cjs} +1 -1
- package/dist/{curveFns-ZuQUBZvd.js → curveFns-B85Glnfo.js} +19 -17
- package/dist/{curveFns-VMxgfkqw.cjs → curveFns-BXCbASW-.cjs} +6 -4
- package/dist/{drawFns-BbhX1IUq.js → drawFns-B-gJ2WUc.js} +47 -21
- package/dist/{drawFns-CKaHgGSK.cjs → drawFns-CAmFEqd1.cjs} +63 -37
- package/dist/{errors-CSYOlCCR.js → errors-Coh_5_19.js} +26 -1
- package/dist/{errors-D13q2HCk.cjs → errors-eRQu29oc.cjs} +26 -1
- package/dist/{faceFns-CfJIbHY3.js → faceFns-CltrEfOo.js} +109 -12
- package/dist/{faceFns-es3GENII.cjs → faceFns-DcndPHWm.cjs} +103 -6
- package/dist/{helpers-C0q_FVxq.cjs → helpers-CC21GeAr.cjs} +8 -9
- package/dist/{helpers-CmVkMubc.js → helpers-SksQIreB.js} +16 -17
- package/dist/index.d.ts +18 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/io/dxfImportFns.d.ts +17 -0
- package/dist/io/dxfImportFns.d.ts.map +1 -0
- package/dist/io/objImportFns.d.ts +19 -0
- package/dist/io/objImportFns.d.ts.map +1 -0
- package/dist/io/threemfImportFns.d.ts +19 -0
- package/dist/io/threemfImportFns.d.ts.map +1 -0
- package/dist/io.cjs +5 -5
- package/dist/io.js +5 -5
- package/dist/kernel/hullOps.d.ts +1 -0
- package/dist/kernel/hullOps.d.ts.map +1 -1
- package/dist/kernel/occtAdapter.d.ts +5 -0
- package/dist/kernel/occtAdapter.d.ts.map +1 -1
- package/dist/kernel/solverAdapter.d.ts +39 -0
- package/dist/kernel/solverAdapter.d.ts.map +1 -0
- package/dist/kernel/types.d.ts +5 -0
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/{loft-B-UCPW9P.cjs → loft-BcyyvWCj.cjs} +28 -28
- package/dist/{loft-oJq2OD3A.js → loft-CJMPx1NQ.js} +16 -16
- package/dist/{measurement-Cf_SoIiR.js → measurement-ByOztLxb.js} +3 -3
- package/dist/{measurement-CYmT-C77.cjs → measurement-DU3ry-0Q.cjs} +3 -3
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-CqNwW0PO.js → meshFns-D2gLyLFt.js} +3 -3
- package/dist/{meshFns-DDC_2U81.cjs → meshFns-DawUwI3W.cjs} +3 -3
- package/dist/{occtBoundary-D_gjqgzo.js → occtBoundary-CWzWqBCm.js} +17 -5
- package/dist/{occtBoundary-CocN2VKx.cjs → occtBoundary-DH2VO-rq.cjs} +12 -0
- package/dist/operations/assemblyFns.d.ts +1 -0
- package/dist/operations/assemblyFns.d.ts.map +1 -1
- package/dist/operations/guidedSweepFns.d.ts +25 -0
- package/dist/operations/guidedSweepFns.d.ts.map +1 -0
- package/dist/operations/mateFns.d.ts +50 -0
- package/dist/operations/mateFns.d.ts.map +1 -0
- package/dist/operations/multiSweepFns.d.ts +32 -0
- package/dist/operations/multiSweepFns.d.ts.map +1 -0
- package/dist/operations/roofFns.d.ts +16 -0
- package/dist/operations/roofFns.d.ts.map +1 -0
- package/dist/operations/straightSkeleton.d.ts +28 -0
- package/dist/operations/straightSkeleton.d.ts.map +1 -0
- package/dist/{operations-BQeW_DSM.cjs → operations-CdELWxgv.cjs} +7 -7
- package/dist/{operations-6hdpuYmY.js → operations-DiXo_4t9.js} +15 -15
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +13 -13
- package/dist/query.cjs +5 -5
- package/dist/query.js +7 -7
- package/dist/result.cjs +1 -1
- package/dist/result.js +1 -1
- package/dist/{shapeFns-B0zSdO9c.cjs → shapeFns-3RYtsUVY.cjs} +54 -21
- package/dist/{shapeFns-k1YHFwmB.js → shapeFns-4ioRrhih.js} +52 -19
- package/dist/{shapeTypes-BxVxLdiD.cjs → shapeTypes-CMjrTv36.cjs} +1 -1
- package/dist/{shapeTypes-c-_pgYCx.js → shapeTypes-D0vfRxWb.js} +13 -13
- package/dist/sketching.cjs +2 -2
- package/dist/sketching.js +2 -2
- package/dist/{curveBuilders-BREwqvuc.js → surfaceBuilders-B7Jxob8g.js} +106 -13
- package/dist/{curveBuilders-BkEJ-RVn.cjs → surfaceBuilders-Xx9DRRxs.cjs} +96 -3
- package/dist/text/textBlueprints.d.ts +38 -0
- package/dist/text/textBlueprints.d.ts.map +1 -1
- package/dist/topology/api.d.ts +5 -0
- package/dist/topology/api.d.ts.map +1 -1
- package/dist/topology/booleanFns.d.ts +10 -1
- package/dist/topology/booleanFns.d.ts.map +1 -1
- package/dist/topology/colorFns.d.ts +38 -0
- package/dist/topology/colorFns.d.ts.map +1 -0
- package/dist/topology/curveFns.d.ts +1 -1
- package/dist/topology/curveFns.d.ts.map +1 -1
- package/dist/topology/faceTagFns.d.ts +44 -0
- package/dist/topology/faceTagFns.d.ts.map +1 -0
- package/dist/topology/modifierFns.d.ts.map +1 -1
- package/dist/topology/polyhedronFns.d.ts +8 -0
- package/dist/topology/polyhedronFns.d.ts.map +1 -0
- package/dist/topology/shapeFns.d.ts +4 -0
- package/dist/topology/shapeFns.d.ts.map +1 -1
- package/dist/topology/surfaceBuilders.d.ts +7 -0
- package/dist/topology/surfaceBuilders.d.ts.map +1 -1
- package/dist/topology/surfaceFns.d.ts +38 -0
- package/dist/topology/surfaceFns.d.ts.map +1 -0
- package/dist/{topology-CycEc6Oe.cjs → topology-D-nGjCzV.cjs} +19 -20
- package/dist/{topology-tMKHJgw2.js → topology-DRP9zreU.js} +8 -9
- package/dist/topology.cjs +13 -14
- package/dist/topology.js +51 -52
- package/dist/{vectors-DE0XriuQ.js → vectors-CZV4ZrTz.js} +2 -2
- package/dist/{vectors-DVmHF4zt.cjs → vectors-DwFeX0Ja.cjs} +2 -2
- package/dist/vectors.cjs +2 -2
- package/dist/vectors.js +2 -2
- package/package.json +4 -3
- package/dist/cast-CPNOTNFm.cjs +0 -102
- package/dist/cast-Cerqtxtb.js +0 -103
package/dist/brepjs.js
CHANGED
|
@@ -1,44 +1,42 @@
|
|
|
1
|
-
import { g as getKernel,
|
|
2
|
-
import { f, h, i, j, r,
|
|
3
|
-
import { l as ok, y as translateOcctError, e as err, q as queryError, x as validationError, B as BrepErrorCode,
|
|
4
|
-
import { O, a, c
|
|
5
|
-
import { c as castShape, k as isSolid, h as isShape3D,
|
|
6
|
-
import { D,
|
|
1
|
+
import { g as getKernel, d as toOcPnt, a as toVec3 } from "./occtBoundary-CWzWqBCm.js";
|
|
2
|
+
import { f, h, i, j, r, b, t, w, k, l } from "./occtBoundary-CWzWqBCm.js";
|
|
3
|
+
import { l as ok, y as translateOcctError, e as err, q as queryError, x as validationError, B as BrepErrorCode, o as occtError, i as ioError, d as isErr, p as typeCastError, u as unwrap } from "./errors-Coh_5_19.js";
|
|
4
|
+
import { O, a, c, b as b2, f as f2, g, m, h as h2, j as j2, k as k2, z, s, t as t2, n, r as r2, v, w as w2 } from "./errors-Coh_5_19.js";
|
|
5
|
+
import { c as castShape, e as isFace, j as isShell, k as isSolid, h as isShape3D, n as gcWithScope, u as createSolid, o as createWire, d as isEdge, m as isWire } from "./shapeTypes-D0vfRxWb.js";
|
|
6
|
+
import { D, s as s2, p, q, a as a2, b as b3, y, t as t3, z as z2, g as g2, i as i2, f as f3, l as l2, r as r3, w as w3 } from "./shapeTypes-D0vfRxWb.js";
|
|
7
7
|
import { c as vecDistance, D as DEG2RAD, n as vecScale, j as vecNormalize, f as vecIsZero } from "./vecOps-ZDdZWbwT.js";
|
|
8
|
-
import { H, R, v as
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import { B as B3, a as a5, b as b5, C as C3, F, S, c as c3, d as d3, f as f6, e as e3, i as i8, g as g7, o as o5, p as p2, r as r5 } from "./boolean2D-DN6ETTCq.js";
|
|
8
|
+
import { H, R, v as v2, a as a3, b as b4, d, e, g as g3, h as h3, i as i3, k as k3, l as l3, m as m2, o } from "./vecOps-ZDdZWbwT.js";
|
|
9
|
+
import { B, d as d2, C, r as r4, t as t4 } from "./Blueprint-Cmh8lKc4.js";
|
|
10
|
+
import { e as curveIsClosed, d as curveStartPoint, c as curveTangentAt, h as curvePointAt, a as curveEndPoint, i as curveLength } from "./curveFns-B85Glnfo.js";
|
|
11
|
+
import { j as j3, k as k4, l as l4, f as f4, m as m3, b as b5, g as g4, n as n2, o as o2 } from "./curveFns-B85Glnfo.js";
|
|
12
|
+
import { m as makeCompound, d as makeCone, e as makeCylinder, f as makeEllipsoid, h as makeOffset, w as weldShellsAndFaces, a as makeSolid, i as makeSphere, j as makeTorus, k as makeVertex } from "./loft-CJMPx1NQ.js";
|
|
13
|
+
import { b as b6, g as g5, r as r5 } from "./loft-CJMPx1NQ.js";
|
|
14
|
+
import { w as walkAssembly, e as extrude$1, r as revolve$1, s as sweep, c as circularPattern, l as linearPattern } from "./operations-DiXo_4t9.js";
|
|
15
|
+
import { a as a4, b as b7, d as d3, f as f5, g as g6, h as h4, i as i4, j as j4, k as k5, m as m4, n as n3, o as o3, p as p2, q as q2, t as t5, u, v as v3, x, y as y2, z as z3, A, B as B2, C as C2, D as D2, E } from "./operations-DiXo_4t9.js";
|
|
16
|
+
import { B as B3, a as a5, e as e2, C as C3, F, S, f as f6, l as l5, g as g7, n as n4, k as k6, q as q3, o as o4, p as p3, r as r6 } from "./boolean2D-D94Axs3i.js";
|
|
18
17
|
import { createBlueprint, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, getBounds2D, getOrientation2D, isInside2D, mirror2D, reverseCurve, rotate2D, scale2D, sketch2DOnFace, sketch2DOnPlane, stretch2D, toSVGPathD, translate2D } from "./2d.js";
|
|
19
|
-
import {
|
|
20
|
-
import { g as g8 } from "./helpers-
|
|
18
|
+
import { l as createTypedFinder, m as faceFinder } from "./helpers-SksQIreB.js";
|
|
19
|
+
import { g as g8 } from "./helpers-SksQIreB.js";
|
|
21
20
|
import { blueprintToDXF, exportDXF, exportGlb, exportGltf, exportOBJ, exportThreeMF, importIGES, importSTEP, importSTL, importSVG, importSVGPathD } from "./io.js";
|
|
22
|
-
import { C as C4, D as D3, a as a6, S as S2, b as
|
|
23
|
-
import { c as
|
|
24
|
-
import { v as vertexPosition,
|
|
25
|
-
import { w as
|
|
26
|
-
import { c as
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import { m as measureArea, a as measureSurfaceProps, b as measureVolumeProps, c as measureVolume } from "./measurement-
|
|
35
|
-
import { d as d8, e as
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import { e as e9, c as c8, d as d9, g as g14, s as s4 } from "./cast-Cerqtxtb.js";
|
|
21
|
+
import { C as C4, D as D3, a as a6, S as S2, b as b8, X, Y, c as c2, d as d4, e as e3, f as f7, Z, g as g9, h as h5, i as i5, j as j5, k as k7, l as l6, m as m5, n as n5, o as o5, p as p4, q as q4, r as r7, s as s3, t as t6, u as u2, v as v4, w as w4, x as x2, y as y3, z as z4, _, $, a0, a1, A as A2, a2 as a22, B as B4, E as E2, a3 as a32, F as F2, G, H as H2, I, J, K, L, M, N, O as O2, P, Q, R as R2, T, U, a4 as a42, V, a5 as a52, a6 as a62, W } from "./drawFns-B-gJ2WUc.js";
|
|
22
|
+
import { c as c3, a as a7, p as p5, r as r8, t as t7 } from "./vectors-CZV4ZrTz.js";
|
|
23
|
+
import { v as vertexPosition, a as getFaces, f as getVertices, d as getEdges, t as translate$1, p as propagateOrigins, h as applyMatrix$1, j as clone$1, k as describe$1, l as isEmpty$1, m as mirror$1, r as rotate$1, s as scale$1, n as simplify$1, o as toBREP$1, q as transformCopy$1, u as getBounds, c as getWires } from "./shapeFns-4ioRrhih.js";
|
|
24
|
+
import { w as w5, g as g10, e as e4, x as x3, i as i6, y as y4, z as z5, A as A3, B as B5, C as C5, D as D4 } from "./shapeFns-4ioRrhih.js";
|
|
25
|
+
import { p as propagateFaceTags, a as propagateColors, c as cut$1, f as fuse$1, i as intersect$1, s as section$1, b as sectionToFace$1, d as slice$1, e as split$1, g as fuseAll, h as cutAll } from "./booleanFns-DdjtpcM6.js";
|
|
26
|
+
import { j as j6, k as k8, l as l7, m as m6, n as n6, o as o6, q as q5, r as r9, t as t8, u as u3 } from "./booleanFns-DdjtpcM6.js";
|
|
27
|
+
import { c as chamferDistAngle, h as heal$1, i as isValid$1 } from "./topology-DRP9zreU.js";
|
|
28
|
+
import { a as a8, b as b9, e as e5, f as f8, d as d5, g as g11, j as j7, s as s4, t as t9, k as k9, l as l8, v as v5, w as w6 } from "./topology-DRP9zreU.js";
|
|
29
|
+
import { i as iterTopo, e as faceCenter, n as normalAt, j as fromBREP$1, k as innerWires, o as outerWire, g as getSurfaceType } from "./faceFns-CltrEfOo.js";
|
|
30
|
+
import { l as l9, c as c4, m as m7, d as d6, f as f9, q as q6, r as r10, s as s5, p as p6, t as t10, v as v6, u as u4, h as h6 } from "./faceFns-CltrEfOo.js";
|
|
31
|
+
import { m as mesh$1, a as meshEdges$1 } from "./meshFns-D2gLyLFt.js";
|
|
32
|
+
import { c as c5, b as b10, e as e6, d as d7, f as f10 } from "./meshFns-D2gLyLFt.js";
|
|
33
|
+
import { m as measureArea, a as measureSurfaceProps, b as measureVolumeProps, c as measureVolume } from "./measurement-ByOztLxb.js";
|
|
34
|
+
import { d as d8, e as e7, f as f11, g as g12, h as h7, i as i7 } from "./measurement-ByOztLxb.js";
|
|
35
|
+
import { h as addHolesInFace, g as makeBezierCurve, k as makeBSplineApproximation, i as makeCircle, j as makeEllipse, f as makeEllipseArc, m as makeFace, n as makeNonPlanarFace, c as makeHelix, a as makeLine, o as makePolygon, l as makeNewFaceWithinFace, e as makeTangentArc, d as makeThreePointArc, b as assembleWire } from "./surfaceBuilders-B7Jxob8g.js";
|
|
36
|
+
import { p as p7 } from "./surfaceBuilders-B7Jxob8g.js";
|
|
39
37
|
import { edgeFinder } from "./query.js";
|
|
40
38
|
import { BrepBugError, bug } from "./result.js";
|
|
41
|
-
import { c as
|
|
39
|
+
import { c as c6 } from "./cornerFinder-BBOYfsXl.js";
|
|
42
40
|
import { createOperationRegistry, createTaskQueue, createWorkerClient, createWorkerHandler, dequeueTask, enqueueTask, isDisposeRequest, isErrorResponse, isInitRequest, isOperationRequest, isQueueEmpty, isSuccessResponse, pendingCount, registerHandler, rejectAll } from "./worker.js";
|
|
43
41
|
const errorFactories = {
|
|
44
42
|
OCCT_OPERATION: (code, message, cause) => ({ kind: "OCCT_OPERATION", code, message, cause }),
|
|
@@ -53,36 +51,36 @@ const errorFactories = {
|
|
|
53
51
|
function kernelCall(fn, code, message, kind = "OCCT_OPERATION") {
|
|
54
52
|
try {
|
|
55
53
|
return ok(castShape(fn()));
|
|
56
|
-
} catch (
|
|
57
|
-
const rawMessage =
|
|
54
|
+
} catch (e8) {
|
|
55
|
+
const rawMessage = e8 instanceof Error ? e8.message : String(e8);
|
|
58
56
|
const translatedMessage = kind === "OCCT_OPERATION" ? translateOcctError(rawMessage) : rawMessage;
|
|
59
|
-
return err(errorFactories[kind](code, `${message}: ${translatedMessage}`,
|
|
57
|
+
return err(errorFactories[kind](code, `${message}: ${translatedMessage}`, e8));
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
60
|
function kernelCallRaw(fn, code, message, kind = "OCCT_OPERATION") {
|
|
63
61
|
try {
|
|
64
62
|
return ok(fn());
|
|
65
|
-
} catch (
|
|
66
|
-
const rawMessage =
|
|
63
|
+
} catch (e8) {
|
|
64
|
+
const rawMessage = e8 instanceof Error ? e8.message : String(e8);
|
|
67
65
|
const translatedMessage = kind === "OCCT_OPERATION" ? translateOcctError(rawMessage) : rawMessage;
|
|
68
|
-
return err(errorFactories[kind](code, `${message}: ${translatedMessage}`,
|
|
66
|
+
return err(errorFactories[kind](code, `${message}: ${translatedMessage}`, e8));
|
|
69
67
|
}
|
|
70
68
|
}
|
|
71
|
-
function isNumber(
|
|
72
|
-
return typeof
|
|
69
|
+
function isNumber(r11) {
|
|
70
|
+
return typeof r11 === "number";
|
|
73
71
|
}
|
|
74
|
-
function isChamferRadius(
|
|
75
|
-
if (typeof
|
|
76
|
-
if (typeof
|
|
77
|
-
const obj =
|
|
72
|
+
function isChamferRadius(r11) {
|
|
73
|
+
if (typeof r11 === "number") return true;
|
|
74
|
+
if (typeof r11 === "object" && r11 !== null) {
|
|
75
|
+
const obj = r11;
|
|
78
76
|
return "distances" in obj && Array.isArray(obj["distances"]) && "selectedFace" in obj || "distance" in obj && "angle" in obj && "selectedFace" in obj;
|
|
79
77
|
}
|
|
80
78
|
return false;
|
|
81
79
|
}
|
|
82
|
-
function isFilletRadius(
|
|
83
|
-
if (typeof
|
|
84
|
-
if (Array.isArray(
|
|
85
|
-
return
|
|
80
|
+
function isFilletRadius(r11) {
|
|
81
|
+
if (typeof r11 === "number") return true;
|
|
82
|
+
if (Array.isArray(r11) && r11.length === 2) {
|
|
83
|
+
return r11.every(isNumber);
|
|
86
84
|
}
|
|
87
85
|
return false;
|
|
88
86
|
}
|
|
@@ -113,11 +111,11 @@ function withNearestPostFilter(baseFinder, nearestPoint) {
|
|
|
113
111
|
if (candidates.length === 0) return [];
|
|
114
112
|
let bestIdx = 0;
|
|
115
113
|
let bestDist = vecDistance(vertexPosition(candidates[0]), nearestPoint);
|
|
116
|
-
for (let
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
bestDist =
|
|
120
|
-
bestIdx =
|
|
114
|
+
for (let i8 = 1; i8 < candidates.length; i8++) {
|
|
115
|
+
const d9 = vecDistance(vertexPosition(candidates[i8]), nearestPoint);
|
|
116
|
+
if (d9 < bestDist) {
|
|
117
|
+
bestDist = d9;
|
|
118
|
+
bestIdx = i8;
|
|
121
119
|
}
|
|
122
120
|
}
|
|
123
121
|
return [candidates[bestIdx]];
|
|
@@ -159,6 +157,261 @@ function buildVertexFinder(filters) {
|
|
|
159
157
|
function vertexFinder() {
|
|
160
158
|
return buildVertexFinder([]);
|
|
161
159
|
}
|
|
160
|
+
function surfaceFromGrid(heights, options = {}) {
|
|
161
|
+
if (heights.length < 2) {
|
|
162
|
+
return err(
|
|
163
|
+
validationError(
|
|
164
|
+
BrepErrorCode.SURFACE_GRID_TOO_SMALL,
|
|
165
|
+
`surfaceFromGrid: need at least 2 rows, got ${heights.length}`
|
|
166
|
+
)
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
const rows = heights.length;
|
|
170
|
+
const cols = heights[0]?.length ?? 0;
|
|
171
|
+
if (cols < 2) {
|
|
172
|
+
return err(
|
|
173
|
+
validationError(
|
|
174
|
+
BrepErrorCode.SURFACE_GRID_TOO_SMALL,
|
|
175
|
+
`surfaceFromGrid: need at least 2 columns, got ${cols}`
|
|
176
|
+
)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
for (let r11 = 0; r11 < rows; r11++) {
|
|
180
|
+
const row = heights[r11];
|
|
181
|
+
if (!row || row.length !== cols) {
|
|
182
|
+
return err(
|
|
183
|
+
validationError(
|
|
184
|
+
BrepErrorCode.SURFACE_GRID_JAGGED,
|
|
185
|
+
`surfaceFromGrid: row ${r11} has ${row?.length ?? 0} columns, expected ${cols}`
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const { width = cols - 1, depth = rows - 1, scaleZ = 1 } = options;
|
|
191
|
+
const dx = width / (cols - 1);
|
|
192
|
+
const dy = depth / (rows - 1);
|
|
193
|
+
try {
|
|
194
|
+
return buildBSplineSurface(heights, rows, cols, dx, dy, scaleZ);
|
|
195
|
+
} catch {
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
return buildTriangulatedSurface(heights, rows, cols, dx, dy, scaleZ);
|
|
199
|
+
} catch (e8) {
|
|
200
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
201
|
+
return err(occtError(BrepErrorCode.SURFACE_FAILED, `surfaceFromGrid failed: ${raw}`, e8));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function buildBSplineSurface(heights, rows, cols, dx, dy, scaleZ) {
|
|
205
|
+
const oc = getKernel().oc;
|
|
206
|
+
const OC = oc;
|
|
207
|
+
const pntArray = new OC.TColgp_Array2OfPnt_2(1, rows, 1, cols);
|
|
208
|
+
try {
|
|
209
|
+
for (let r11 = 0; r11 < rows; r11++) {
|
|
210
|
+
for (let c7 = 0; c7 < cols; c7++) {
|
|
211
|
+
const row = heights[r11];
|
|
212
|
+
const z6 = (row ? row[c7] ?? 0 : 0) * scaleZ;
|
|
213
|
+
const pnt = new oc.gp_Pnt_3(c7 * dx, r11 * dy, z6);
|
|
214
|
+
pntArray.SetValue(r11 + 1, c7 + 1, pnt);
|
|
215
|
+
pnt.delete();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const fitter = new OC.GeomAPI_PointsToBSplineSurface_2(pntArray, 3, 8, 0, 1e-3);
|
|
219
|
+
const surface = fitter.Surface();
|
|
220
|
+
const faceMaker = new OC.BRepBuilderAPI_MakeFace_8(surface, 1e-6);
|
|
221
|
+
let result;
|
|
222
|
+
if (faceMaker.IsDone()) {
|
|
223
|
+
const shape2 = castShape(faceMaker.Face());
|
|
224
|
+
if (isFace(shape2)) {
|
|
225
|
+
result = ok(shape2);
|
|
226
|
+
} else {
|
|
227
|
+
shape2[Symbol.dispose]();
|
|
228
|
+
result = err(
|
|
229
|
+
occtError(BrepErrorCode.SURFACE_FAILED, "B-spline surface did not produce a face")
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
result = err(
|
|
234
|
+
occtError(
|
|
235
|
+
BrepErrorCode.SURFACE_FAILED,
|
|
236
|
+
"BRepBuilderAPI_MakeFace failed for B-spline surface"
|
|
237
|
+
)
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
faceMaker.delete();
|
|
241
|
+
fitter.delete();
|
|
242
|
+
return result;
|
|
243
|
+
} finally {
|
|
244
|
+
pntArray.delete();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function buildTriangulatedSurface(heights, rows, cols, dx, dy, scaleZ) {
|
|
248
|
+
const oc = getKernel().oc;
|
|
249
|
+
function pt(r11, c7) {
|
|
250
|
+
const row = heights[r11];
|
|
251
|
+
const z6 = (row ? row[c7] ?? 0 : 0) * scaleZ;
|
|
252
|
+
return { x: c7 * dx, y: r11 * dy, z: z6 };
|
|
253
|
+
}
|
|
254
|
+
function buildTriFace2(a9, b11, c7) {
|
|
255
|
+
const gpA = new oc.gp_Pnt_3(a9.x, a9.y, a9.z);
|
|
256
|
+
const gpB = new oc.gp_Pnt_3(b11.x, b11.y, b11.z);
|
|
257
|
+
const gpC = new oc.gp_Pnt_3(c7.x, c7.y, c7.z);
|
|
258
|
+
const e1 = new oc.BRepBuilderAPI_MakeEdge_3(gpA, gpB);
|
|
259
|
+
const e22 = new oc.BRepBuilderAPI_MakeEdge_3(gpB, gpC);
|
|
260
|
+
const e32 = new oc.BRepBuilderAPI_MakeEdge_3(gpC, gpA);
|
|
261
|
+
const wireBuilder = new oc.BRepBuilderAPI_MakeWire_1();
|
|
262
|
+
wireBuilder.Add_1(e1.Edge());
|
|
263
|
+
wireBuilder.Add_1(e22.Edge());
|
|
264
|
+
wireBuilder.Add_1(e32.Edge());
|
|
265
|
+
let face2 = null;
|
|
266
|
+
if (wireBuilder.IsDone()) {
|
|
267
|
+
const makeFace2 = new oc.BRepBuilderAPI_MakeFace_15(wireBuilder.Wire(), false);
|
|
268
|
+
if (makeFace2.IsDone()) {
|
|
269
|
+
face2 = makeFace2.Face();
|
|
270
|
+
}
|
|
271
|
+
makeFace2.delete();
|
|
272
|
+
}
|
|
273
|
+
wireBuilder.delete();
|
|
274
|
+
e1.delete();
|
|
275
|
+
e22.delete();
|
|
276
|
+
e32.delete();
|
|
277
|
+
gpA.delete();
|
|
278
|
+
gpB.delete();
|
|
279
|
+
gpC.delete();
|
|
280
|
+
return face2;
|
|
281
|
+
}
|
|
282
|
+
const sewing = new oc.BRepBuilderAPI_Sewing(1e-6, true, true, true, false);
|
|
283
|
+
let faceCount = 0;
|
|
284
|
+
try {
|
|
285
|
+
for (let r11 = 0; r11 < rows - 1; r11++) {
|
|
286
|
+
for (let c7 = 0; c7 < cols - 1; c7++) {
|
|
287
|
+
const p00 = pt(r11, c7);
|
|
288
|
+
const p10 = pt(r11 + 1, c7);
|
|
289
|
+
const p11 = pt(r11 + 1, c7 + 1);
|
|
290
|
+
const p01 = pt(r11, c7 + 1);
|
|
291
|
+
const f1 = buildTriFace2(p00, p10, p11);
|
|
292
|
+
if (f1 !== null) {
|
|
293
|
+
sewing.Add(f1);
|
|
294
|
+
faceCount++;
|
|
295
|
+
}
|
|
296
|
+
const f22 = buildTriFace2(p00, p11, p01);
|
|
297
|
+
if (f22 !== null) {
|
|
298
|
+
sewing.Add(f22);
|
|
299
|
+
faceCount++;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (faceCount === 0) {
|
|
304
|
+
sewing.delete();
|
|
305
|
+
return err(
|
|
306
|
+
occtError(BrepErrorCode.SURFACE_FAILED, "surfaceFromGrid: no valid triangular faces built")
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
const sewProgress = new oc.Message_ProgressRange_1();
|
|
310
|
+
sewing.Perform(sewProgress);
|
|
311
|
+
sewProgress.delete();
|
|
312
|
+
const sewn = sewing.SewedShape();
|
|
313
|
+
const shape2 = castShape(sewn);
|
|
314
|
+
if (isFace(shape2)) {
|
|
315
|
+
return ok(shape2);
|
|
316
|
+
}
|
|
317
|
+
if (isShell(shape2)) {
|
|
318
|
+
return ok(shape2);
|
|
319
|
+
}
|
|
320
|
+
shape2[Symbol.dispose]();
|
|
321
|
+
return err(
|
|
322
|
+
occtError(BrepErrorCode.SURFACE_FAILED, "surfaceFromGrid: unexpected shape type from sewing")
|
|
323
|
+
);
|
|
324
|
+
} finally {
|
|
325
|
+
sewing.delete();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
async function surfaceFromImage(blob, options = {}) {
|
|
329
|
+
const channel = options.channel ?? "luminance";
|
|
330
|
+
const downsample = Math.max(1, Math.round(options.downsample ?? 1));
|
|
331
|
+
if (typeof createImageBitmap !== "function") {
|
|
332
|
+
return err(
|
|
333
|
+
ioError(
|
|
334
|
+
BrepErrorCode.SURFACE_FAILED,
|
|
335
|
+
"surfaceFromImage requires createImageBitmap (not available in this environment)"
|
|
336
|
+
)
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
let bitmap;
|
|
340
|
+
try {
|
|
341
|
+
bitmap = await createImageBitmap(blob);
|
|
342
|
+
} catch (e8) {
|
|
343
|
+
return err(
|
|
344
|
+
ioError(
|
|
345
|
+
BrepErrorCode.SURFACE_FAILED,
|
|
346
|
+
`surfaceFromImage: failed to decode image — ${e8 instanceof Error ? e8.message : String(e8)}`
|
|
347
|
+
)
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
const w7 = bitmap.width;
|
|
351
|
+
const h8 = bitmap.height;
|
|
352
|
+
if (w7 < 2 || h8 < 2) {
|
|
353
|
+
bitmap.close();
|
|
354
|
+
return err(
|
|
355
|
+
validationError(
|
|
356
|
+
BrepErrorCode.SURFACE_GRID_TOO_SMALL,
|
|
357
|
+
`surfaceFromImage: image too small (${w7}x${h8}), need at least 2x2`
|
|
358
|
+
)
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
if (typeof OffscreenCanvas !== "function") {
|
|
362
|
+
bitmap.close();
|
|
363
|
+
return err(
|
|
364
|
+
ioError(
|
|
365
|
+
BrepErrorCode.SURFACE_FAILED,
|
|
366
|
+
"surfaceFromImage requires OffscreenCanvas (not available in this environment)"
|
|
367
|
+
)
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
const canvas = new OffscreenCanvas(w7, h8);
|
|
371
|
+
const ctx = canvas.getContext("2d");
|
|
372
|
+
if (!ctx) {
|
|
373
|
+
bitmap.close();
|
|
374
|
+
return err(
|
|
375
|
+
ioError(BrepErrorCode.SURFACE_FAILED, "surfaceFromImage: could not get 2D canvas context")
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
379
|
+
bitmap.close();
|
|
380
|
+
const imageData = ctx.getImageData(0, 0, w7, h8);
|
|
381
|
+
const data = imageData.data;
|
|
382
|
+
const rows = [];
|
|
383
|
+
for (let y5 = 0; y5 < h8; y5 += downsample) {
|
|
384
|
+
const row = [];
|
|
385
|
+
for (let x4 = 0; x4 < w7; x4 += downsample) {
|
|
386
|
+
const idx = (y5 * w7 + x4) * 4;
|
|
387
|
+
const r11 = data[idx] ?? 0;
|
|
388
|
+
const g13 = data[idx + 1] ?? 0;
|
|
389
|
+
const b11 = data[idx + 2] ?? 0;
|
|
390
|
+
let value;
|
|
391
|
+
switch (channel) {
|
|
392
|
+
case "r":
|
|
393
|
+
value = r11 / 255;
|
|
394
|
+
break;
|
|
395
|
+
case "g":
|
|
396
|
+
value = g13 / 255;
|
|
397
|
+
break;
|
|
398
|
+
case "b":
|
|
399
|
+
value = b11 / 255;
|
|
400
|
+
break;
|
|
401
|
+
default:
|
|
402
|
+
value = (0.299 * r11 + 0.587 * g13 + 0.114 * b11) / 255;
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
row.push(value);
|
|
406
|
+
}
|
|
407
|
+
rows.push(row);
|
|
408
|
+
}
|
|
409
|
+
const gridOpts = {};
|
|
410
|
+
if (options.width !== void 0) gridOpts.width = options.width;
|
|
411
|
+
if (options.depth !== void 0) gridOpts.depth = options.depth;
|
|
412
|
+
if (options.scaleZ !== void 0) gridOpts.scaleZ = options.scaleZ;
|
|
413
|
+
return surfaceFromGrid(rows, gridOpts);
|
|
414
|
+
}
|
|
162
415
|
function validateNotNull$1(shape2, label) {
|
|
163
416
|
if (shape2.wrapped.IsNull()) {
|
|
164
417
|
return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `${label} is a null shape`));
|
|
@@ -177,14 +430,14 @@ function hull(shapes, options = {}) {
|
|
|
177
430
|
)
|
|
178
431
|
);
|
|
179
432
|
}
|
|
180
|
-
for (const [
|
|
181
|
-
const check = validateNotNull$1(shape2, `hull: shapes[${
|
|
433
|
+
for (const [i8, shape2] of shapes.entries()) {
|
|
434
|
+
const check = validateNotNull$1(shape2, `hull: shapes[${i8}]`);
|
|
182
435
|
if (isErr(check)) return check;
|
|
183
436
|
}
|
|
184
437
|
const tolerance = options.tolerance ?? 0.1;
|
|
185
438
|
try {
|
|
186
439
|
const kernel = getKernel();
|
|
187
|
-
const ocShapes = shapes.map((
|
|
440
|
+
const ocShapes = shapes.map((s6) => s6.wrapped);
|
|
188
441
|
const resultOc = kernel.hull(ocShapes, tolerance);
|
|
189
442
|
const cast = castShape(resultOc);
|
|
190
443
|
if (!isSolid(cast)) {
|
|
@@ -193,12 +446,12 @@ function hull(shapes, options = {}) {
|
|
|
193
446
|
);
|
|
194
447
|
}
|
|
195
448
|
return ok(cast);
|
|
196
|
-
} catch (
|
|
197
|
-
const raw =
|
|
449
|
+
} catch (e8) {
|
|
450
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
198
451
|
if (raw.includes("coplanar") || raw.includes("fewer than") || raw.includes("degenerate")) {
|
|
199
|
-
return err(occtError(BrepErrorCode.HULL_DEGENERATE, `Hull degenerate: ${raw}`,
|
|
452
|
+
return err(occtError(BrepErrorCode.HULL_DEGENERATE, `Hull degenerate: ${raw}`, e8));
|
|
200
453
|
}
|
|
201
|
-
return err(occtError(BrepErrorCode.HULL_FAILED, `Hull operation failed: ${raw}`,
|
|
454
|
+
return err(occtError(BrepErrorCode.HULL_FAILED, `Hull operation failed: ${raw}`, e8));
|
|
202
455
|
}
|
|
203
456
|
}
|
|
204
457
|
function detectSphere(shape2) {
|
|
@@ -206,8 +459,8 @@ function detectSphere(shape2) {
|
|
|
206
459
|
const faces = getFaces(shape2);
|
|
207
460
|
if (faces.length !== 1) return null;
|
|
208
461
|
const face2 = faces[0];
|
|
209
|
-
const
|
|
210
|
-
const adaptor =
|
|
462
|
+
const r11 = gcWithScope();
|
|
463
|
+
const adaptor = r11(new oc.BRepAdaptor_Surface_2(face2.wrapped, true));
|
|
211
464
|
const surfType = adaptor.GetType();
|
|
212
465
|
if (surfType !== oc.GeomAbs_SurfaceType.GeomAbs_Sphere) return null;
|
|
213
466
|
const ocSphere = adaptor.Sphere();
|
|
@@ -217,10 +470,10 @@ function detectSphere(shape2) {
|
|
|
217
470
|
}
|
|
218
471
|
function minkowskiSphere(shape2, radius, tolerance) {
|
|
219
472
|
const oc = getKernel().oc;
|
|
220
|
-
const
|
|
473
|
+
const r11 = gcWithScope();
|
|
221
474
|
try {
|
|
222
|
-
const offsetMaker =
|
|
223
|
-
const progress =
|
|
475
|
+
const offsetMaker = r11(new oc.BRepOffsetAPI_MakeOffsetShape());
|
|
476
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
224
477
|
offsetMaker.PerformByJoin(
|
|
225
478
|
shape2.wrapped,
|
|
226
479
|
radius,
|
|
@@ -244,10 +497,10 @@ function minkowskiSphere(shape2, radius, tolerance) {
|
|
|
244
497
|
);
|
|
245
498
|
}
|
|
246
499
|
return ok(wrapped);
|
|
247
|
-
} catch (
|
|
248
|
-
const raw =
|
|
500
|
+
} catch (e8) {
|
|
501
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
249
502
|
return err(
|
|
250
|
-
occtError(BrepErrorCode.MINKOWSKI_FAILED, `Minkowski sphere offset failed: ${raw}`,
|
|
503
|
+
occtError(BrepErrorCode.MINKOWSKI_FAILED, `Minkowski sphere offset failed: ${raw}`, e8, {
|
|
251
504
|
operation: "minkowski",
|
|
252
505
|
fastPath: "sphere"
|
|
253
506
|
})
|
|
@@ -293,10 +546,10 @@ function minkowskiGeneral(shape2, tool, _tolerance) {
|
|
|
293
546
|
);
|
|
294
547
|
}
|
|
295
548
|
return ok(wrapped);
|
|
296
|
-
} catch (
|
|
297
|
-
const raw =
|
|
549
|
+
} catch (e8) {
|
|
550
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
298
551
|
return err(
|
|
299
|
-
occtError(BrepErrorCode.MINKOWSKI_FAILED, `Minkowski general path failed: ${raw}`,
|
|
552
|
+
occtError(BrepErrorCode.MINKOWSKI_FAILED, `Minkowski general path failed: ${raw}`, e8, {
|
|
300
553
|
operation: "minkowski"
|
|
301
554
|
})
|
|
302
555
|
);
|
|
@@ -323,6 +576,809 @@ function minkowski(shape2, tool, options = {}) {
|
|
|
323
576
|
}
|
|
324
577
|
return minkowskiGeneral(shape2, tool, tolerance);
|
|
325
578
|
}
|
|
579
|
+
function polyhedron(points, faces, options = {}) {
|
|
580
|
+
const { tolerance = 1e-6 } = options;
|
|
581
|
+
if (points.length < 4) {
|
|
582
|
+
return err(
|
|
583
|
+
validationError(
|
|
584
|
+
BrepErrorCode.POLYHEDRON_INSUFFICIENT_POINTS,
|
|
585
|
+
`polyhedron: need at least 4 points, got ${points.length}`
|
|
586
|
+
)
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
if (faces.length < 4) {
|
|
590
|
+
return err(
|
|
591
|
+
validationError(
|
|
592
|
+
BrepErrorCode.POLYHEDRON_INSUFFICIENT_FACES,
|
|
593
|
+
`polyhedron: need at least 4 faces, got ${faces.length}`
|
|
594
|
+
)
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
const triangles = [];
|
|
598
|
+
for (const [fi, face2] of faces.entries()) {
|
|
599
|
+
for (const idx of face2) {
|
|
600
|
+
if (idx < 0 || idx >= points.length) {
|
|
601
|
+
return err(
|
|
602
|
+
validationError(
|
|
603
|
+
BrepErrorCode.POLYHEDRON_INVALID_INDEX,
|
|
604
|
+
`polyhedron: face ${fi} has out-of-range index ${idx} (${points.length} points)`
|
|
605
|
+
)
|
|
606
|
+
);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
if (face2.length < 3) continue;
|
|
610
|
+
const v0 = face2[0];
|
|
611
|
+
for (let i8 = 1; i8 < face2.length - 1; i8++) {
|
|
612
|
+
triangles.push([v0, face2[i8], face2[i8 + 1]]);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
try {
|
|
616
|
+
const kernel = getKernel();
|
|
617
|
+
const ptObjs = points.map(([x4, y5, z6]) => ({ x: x4, y: y5, z: z6 }));
|
|
618
|
+
const resultOc = kernel.buildSolidFromFaces(ptObjs, triangles, tolerance);
|
|
619
|
+
const cast = castShape(resultOc);
|
|
620
|
+
if (!isSolid(cast)) {
|
|
621
|
+
cast[Symbol.dispose]();
|
|
622
|
+
return err(occtError(BrepErrorCode.POLYHEDRON_FAILED, "Polyhedron did not produce a solid"));
|
|
623
|
+
}
|
|
624
|
+
return ok(cast);
|
|
625
|
+
} catch (e8) {
|
|
626
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
627
|
+
return err(occtError(BrepErrorCode.POLYHEDRON_FAILED, `Polyhedron failed: ${raw}`, e8));
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
function multiSectionSweep(sections, spine, options) {
|
|
631
|
+
if (sections.length < 2) {
|
|
632
|
+
return err(
|
|
633
|
+
validationError(
|
|
634
|
+
BrepErrorCode.MULTI_SWEEP_INSUFFICIENT_SECTIONS,
|
|
635
|
+
`Multi-section sweep requires at least 2 sections, got ${sections.length}`
|
|
636
|
+
)
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
const { solid: solid2 = true, ruled = false, tolerance = 1e-6 } = options ?? {};
|
|
640
|
+
try {
|
|
641
|
+
const oc = getKernel().oc;
|
|
642
|
+
const r11 = gcWithScope();
|
|
643
|
+
const adaptor = r11(new oc.BRepAdaptor_CompCurve_2(spine.wrapped, false));
|
|
644
|
+
const uFirst = Number(adaptor.FirstParameter());
|
|
645
|
+
const uLast = Number(adaptor.LastParameter());
|
|
646
|
+
const uRange = uLast - uFirst;
|
|
647
|
+
const params = sections.map((s6, i8) => {
|
|
648
|
+
if (s6.location !== void 0) {
|
|
649
|
+
return uFirst + s6.location * uRange;
|
|
650
|
+
}
|
|
651
|
+
return uFirst + i8 / (sections.length - 1) * uRange;
|
|
652
|
+
});
|
|
653
|
+
const builder = r11(new oc.BRepOffsetAPI_ThruSections(solid2, ruled, tolerance));
|
|
654
|
+
for (let i8 = 0; i8 < sections.length; i8++) {
|
|
655
|
+
const param = params[i8];
|
|
656
|
+
const section2 = sections[i8];
|
|
657
|
+
if (param === void 0 || section2 === void 0) continue;
|
|
658
|
+
const pnt = r11(new oc.gp_Pnt_1());
|
|
659
|
+
const tangent = r11(new oc.gp_Vec_1());
|
|
660
|
+
adaptor.D1(param, pnt, tangent);
|
|
661
|
+
const tangentDir = r11(new oc.gp_Dir_2(tangent));
|
|
662
|
+
const toAx3 = r11(new oc.gp_Ax3_4(pnt, tangentDir));
|
|
663
|
+
const trsf = r11(new oc.gp_Trsf_1());
|
|
664
|
+
trsf.SetTransformation_2(toAx3);
|
|
665
|
+
trsf.Invert();
|
|
666
|
+
const transformer = r11(new oc.BRepBuilderAPI_Transform_2(section2.wire.wrapped, trsf, true));
|
|
667
|
+
const transformedShape = transformer.Shape();
|
|
668
|
+
const transformedWire = oc.TopoDS.Wire_1(transformedShape);
|
|
669
|
+
builder.AddWire(transformedWire);
|
|
670
|
+
}
|
|
671
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
672
|
+
builder.Build(progress);
|
|
673
|
+
if (!builder.IsDone()) {
|
|
674
|
+
return err(occtError(BrepErrorCode.MULTI_SWEEP_FAILED, "Multi-section sweep build failed"));
|
|
675
|
+
}
|
|
676
|
+
const result = castShape(builder.Shape());
|
|
677
|
+
if (!isShape3D(result)) {
|
|
678
|
+
return err(
|
|
679
|
+
typeCastError("MULTI_SWEEP_NOT_3D", "Multi-section sweep did not produce a 3D shape")
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
return ok(result);
|
|
683
|
+
} catch (e8) {
|
|
684
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
685
|
+
return err(
|
|
686
|
+
occtError(BrepErrorCode.MULTI_SWEEP_FAILED, `Multi-section sweep failed: ${raw}`, e8)
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
function guidedSweep(profile, spine, guides, options = {}) {
|
|
691
|
+
const { transition = "transformed", solid: solid2 = true, tolerance } = options;
|
|
692
|
+
try {
|
|
693
|
+
const oc = getKernel().oc;
|
|
694
|
+
const r11 = gcWithScope();
|
|
695
|
+
const builder = r11(new oc.BRepOffsetAPI_MakePipeShell(spine.wrapped));
|
|
696
|
+
const modeMap = {
|
|
697
|
+
transformed: oc.BRepBuilderAPI_TransitionMode.BRepBuilderAPI_Transformed,
|
|
698
|
+
round: oc.BRepBuilderAPI_TransitionMode.BRepBuilderAPI_RoundCorner,
|
|
699
|
+
right: oc.BRepBuilderAPI_TransitionMode.BRepBuilderAPI_RightCorner
|
|
700
|
+
};
|
|
701
|
+
builder.SetTransitionMode(modeMap[transition]);
|
|
702
|
+
if (tolerance !== void 0) {
|
|
703
|
+
builder.SetTolerance(tolerance, tolerance, 1e-7);
|
|
704
|
+
}
|
|
705
|
+
if (guides.length > 0) {
|
|
706
|
+
const firstGuide = guides[0];
|
|
707
|
+
builder.SetMode_5(firstGuide.wrapped, false, oc.BRepFill_TypeOfContact.BRepFill_NoContact);
|
|
708
|
+
}
|
|
709
|
+
builder.Add_1(profile.wrapped, false, false);
|
|
710
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
711
|
+
builder.Build(progress);
|
|
712
|
+
if (!builder.IsDone()) {
|
|
713
|
+
return err(occtError(BrepErrorCode.GUIDED_SWEEP_FAILED, "Guided sweep build failed"));
|
|
714
|
+
}
|
|
715
|
+
if (solid2) {
|
|
716
|
+
builder.MakeSolid();
|
|
717
|
+
}
|
|
718
|
+
const result = castShape(builder.Shape());
|
|
719
|
+
if (!isShape3D(result)) {
|
|
720
|
+
return err(typeCastError("GUIDED_SWEEP_NOT_3D", "Guided sweep did not produce a 3D shape"));
|
|
721
|
+
}
|
|
722
|
+
return ok(result);
|
|
723
|
+
} catch (e8) {
|
|
724
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
725
|
+
return err(occtError(BrepErrorCode.GUIDED_SWEEP_FAILED, `Guided sweep failed: ${raw}`, e8));
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
const EPS = 1e-10;
|
|
729
|
+
function cross2(ax, ay, bx, by) {
|
|
730
|
+
return ax * by - ay * bx;
|
|
731
|
+
}
|
|
732
|
+
function dot2(ax, ay, bx, by) {
|
|
733
|
+
return ax * bx + ay * by;
|
|
734
|
+
}
|
|
735
|
+
function len2(x4, y5) {
|
|
736
|
+
return Math.sqrt(x4 * x4 + y5 * y5);
|
|
737
|
+
}
|
|
738
|
+
function polyAt(poly, i8) {
|
|
739
|
+
const p8 = poly[(i8 % poly.length + poly.length) % poly.length];
|
|
740
|
+
if (!p8) throw new Error(`Invalid polygon index ${i8} for length ${poly.length}`);
|
|
741
|
+
return p8;
|
|
742
|
+
}
|
|
743
|
+
function ensureCCW(poly) {
|
|
744
|
+
let area = 0;
|
|
745
|
+
for (let i8 = 0; i8 < poly.length; i8++) {
|
|
746
|
+
const cur = polyAt(poly, i8);
|
|
747
|
+
const nxt = polyAt(poly, i8 + 1);
|
|
748
|
+
area += cur.x * nxt.y - nxt.x * cur.y;
|
|
749
|
+
}
|
|
750
|
+
if (area < 0) return [...poly].reverse();
|
|
751
|
+
return poly;
|
|
752
|
+
}
|
|
753
|
+
function bisector(poly, i8) {
|
|
754
|
+
const prev = polyAt(poly, i8 - 1);
|
|
755
|
+
const cur = polyAt(poly, i8);
|
|
756
|
+
const next = polyAt(poly, i8 + 1);
|
|
757
|
+
const e1x = cur.x - prev.x;
|
|
758
|
+
const e1y = cur.y - prev.y;
|
|
759
|
+
const e1l = len2(e1x, e1y);
|
|
760
|
+
const e2x = next.x - cur.x;
|
|
761
|
+
const e2y = next.y - cur.y;
|
|
762
|
+
const e2l = len2(e2x, e2y);
|
|
763
|
+
if (e1l < EPS || e2l < EPS) return { dx: 0, dy: 0 };
|
|
764
|
+
const n1x = -e1y / e1l;
|
|
765
|
+
const n1y = e1x / e1l;
|
|
766
|
+
const n2x = -e2y / e2l;
|
|
767
|
+
const n2y = e2x / e2l;
|
|
768
|
+
let bx = n1x + n2x;
|
|
769
|
+
let by = n1y + n2y;
|
|
770
|
+
const bl = len2(bx, by);
|
|
771
|
+
if (bl < EPS) {
|
|
772
|
+
return { dx: n1x, dy: n1y };
|
|
773
|
+
}
|
|
774
|
+
bx /= bl;
|
|
775
|
+
by /= bl;
|
|
776
|
+
const cosHalf = dot2(bx, by, n1x, n1y);
|
|
777
|
+
const speed = Math.abs(cosHalf) > EPS ? 1 / cosHalf : 1;
|
|
778
|
+
return { dx: bx * speed, dy: by * speed };
|
|
779
|
+
}
|
|
780
|
+
function isLavNodeReflex(node) {
|
|
781
|
+
const prev = node.prev;
|
|
782
|
+
const next = node.next;
|
|
783
|
+
return cross2(node.x - prev.x, node.y - prev.y, next.x - node.x, next.y - node.y) < -EPS;
|
|
784
|
+
}
|
|
785
|
+
function createLav(poly) {
|
|
786
|
+
const nodes = poly.map((p8, i8) => {
|
|
787
|
+
const b11 = bisector(poly, i8);
|
|
788
|
+
return {
|
|
789
|
+
x: p8.x,
|
|
790
|
+
y: p8.y,
|
|
791
|
+
bx: b11.dx,
|
|
792
|
+
by: b11.dy,
|
|
793
|
+
origIdx: i8,
|
|
794
|
+
prev: null,
|
|
795
|
+
next: null,
|
|
796
|
+
active: true
|
|
797
|
+
};
|
|
798
|
+
});
|
|
799
|
+
for (let i8 = 0; i8 < nodes.length; i8++) {
|
|
800
|
+
const node = nodes[i8];
|
|
801
|
+
const prevNode = nodes[(i8 - 1 + nodes.length) % nodes.length];
|
|
802
|
+
const nextNode = nodes[(i8 + 1) % nodes.length];
|
|
803
|
+
if (node && prevNode && nextNode) {
|
|
804
|
+
node.prev = prevNode;
|
|
805
|
+
node.next = nextNode;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
return nodes;
|
|
809
|
+
}
|
|
810
|
+
function lavSize(start) {
|
|
811
|
+
let count = 1;
|
|
812
|
+
let cur = start.next;
|
|
813
|
+
while (cur !== start) {
|
|
814
|
+
count++;
|
|
815
|
+
cur = cur.next;
|
|
816
|
+
if (count > 1e4) break;
|
|
817
|
+
}
|
|
818
|
+
return count;
|
|
819
|
+
}
|
|
820
|
+
function bisectorIntersectTime(a9, b11) {
|
|
821
|
+
const ddx = a9.bx - b11.bx;
|
|
822
|
+
const ddy = a9.by - b11.by;
|
|
823
|
+
const dxp = b11.x - a9.x;
|
|
824
|
+
const dyp = b11.y - a9.y;
|
|
825
|
+
if (Math.abs(ddx) < EPS && Math.abs(ddy) < EPS) return null;
|
|
826
|
+
let t11;
|
|
827
|
+
if (Math.abs(ddx) > Math.abs(ddy)) {
|
|
828
|
+
t11 = dxp / ddx;
|
|
829
|
+
} else {
|
|
830
|
+
t11 = dyp / ddy;
|
|
831
|
+
}
|
|
832
|
+
if (t11 < EPS) return null;
|
|
833
|
+
const otherDd = Math.abs(ddx) > Math.abs(ddy) ? ddy : ddx;
|
|
834
|
+
const otherDp = Math.abs(ddx) > Math.abs(ddy) ? dyp : dxp;
|
|
835
|
+
if (Math.abs(otherDd) > EPS) {
|
|
836
|
+
const t22 = otherDp / otherDd;
|
|
837
|
+
if (Math.abs(t11 - t22) > 1e-4 * Math.max(1, Math.abs(t11))) return null;
|
|
838
|
+
}
|
|
839
|
+
return t11;
|
|
840
|
+
}
|
|
841
|
+
function raySplitTime(node, eA, eB) {
|
|
842
|
+
const edx = eB.x - eA.x;
|
|
843
|
+
const edy = eB.y - eA.y;
|
|
844
|
+
const el = len2(edx, edy);
|
|
845
|
+
if (el < EPS) return null;
|
|
846
|
+
const enx = -edy / el;
|
|
847
|
+
const eny = edx / el;
|
|
848
|
+
const d0 = (node.x - eA.x) * enx + (node.y - eA.y) * eny;
|
|
849
|
+
const relBx = node.bx - (eA.bx + eB.bx) / 2;
|
|
850
|
+
const relBy = node.by - (eA.by + eB.by) / 2;
|
|
851
|
+
const dRate = relBx * enx + relBy * eny;
|
|
852
|
+
if (Math.abs(dRate) < EPS) return null;
|
|
853
|
+
const t11 = -d0 / dRate;
|
|
854
|
+
if (t11 < EPS) return null;
|
|
855
|
+
const px = node.x + t11 * node.bx;
|
|
856
|
+
const py = node.y + t11 * node.by;
|
|
857
|
+
const ax = eA.x + t11 * eA.bx;
|
|
858
|
+
const ay = eA.y + t11 * eA.by;
|
|
859
|
+
const bxx = eB.x + t11 * eB.bx;
|
|
860
|
+
const byy = eB.y + t11 * eB.by;
|
|
861
|
+
const segDx = bxx - ax;
|
|
862
|
+
const segDy = byy - ay;
|
|
863
|
+
const segL = len2(segDx, segDy);
|
|
864
|
+
if (segL < EPS) return t11;
|
|
865
|
+
const s6 = dot2(px - ax, py - ay, segDx, segDy) / (segL * segL);
|
|
866
|
+
if (s6 < -0.01 || s6 > 1.01) return null;
|
|
867
|
+
return t11;
|
|
868
|
+
}
|
|
869
|
+
function computeEvents(lavNodes) {
|
|
870
|
+
const events = [];
|
|
871
|
+
for (const node of lavNodes) {
|
|
872
|
+
if (!node.active) continue;
|
|
873
|
+
const t11 = bisectorIntersectTime(node, node.next);
|
|
874
|
+
if (t11 !== null && t11 > EPS) {
|
|
875
|
+
const x4 = node.x + t11 * node.bx;
|
|
876
|
+
const y5 = node.y + t11 * node.by;
|
|
877
|
+
events.push({ time: t11, x: x4, y: y5, nodeA: node, nodeB: node.next, type: "edge" });
|
|
878
|
+
}
|
|
879
|
+
if (isLavNodeReflex(node)) {
|
|
880
|
+
let cur = node.next.next;
|
|
881
|
+
let count = 0;
|
|
882
|
+
while (cur !== node.prev && cur !== node && count < 1e3) {
|
|
883
|
+
const st = raySplitTime(node, cur, cur.next);
|
|
884
|
+
if (st !== null && st > EPS) {
|
|
885
|
+
const x4 = node.x + st * node.bx;
|
|
886
|
+
const y5 = node.y + st * node.by;
|
|
887
|
+
events.push({ time: st, x: x4, y: y5, nodeA: node, nodeB: cur, type: "split" });
|
|
888
|
+
}
|
|
889
|
+
cur = cur.next;
|
|
890
|
+
count++;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
events.sort((a9, b11) => a9.time - b11.time);
|
|
895
|
+
return events;
|
|
896
|
+
}
|
|
897
|
+
function computeStraightSkeleton(polygon2) {
|
|
898
|
+
if (polygon2.length < 3) {
|
|
899
|
+
return { nodes: [], faces: [] };
|
|
900
|
+
}
|
|
901
|
+
const poly = ensureCCW(polygon2);
|
|
902
|
+
const n7 = poly.length;
|
|
903
|
+
const skeletonNodes = [];
|
|
904
|
+
const vertexToSkelNodes = Array.from({ length: n7 }, () => []);
|
|
905
|
+
const lavNodes = createLav(poly);
|
|
906
|
+
let iterations = 0;
|
|
907
|
+
const maxIter = n7 * n7 * 2;
|
|
908
|
+
while (iterations < maxIter) {
|
|
909
|
+
iterations++;
|
|
910
|
+
const activeStart = lavNodes.find((nd) => nd.active);
|
|
911
|
+
if (!activeStart) break;
|
|
912
|
+
const sz = lavSize(activeStart);
|
|
913
|
+
if (sz <= 3) {
|
|
914
|
+
if (sz === 3) {
|
|
915
|
+
const a9 = activeStart;
|
|
916
|
+
const b11 = a9.next;
|
|
917
|
+
const c7 = b11.next;
|
|
918
|
+
const t11 = bisectorIntersectTime(a9, b11);
|
|
919
|
+
const time = t11 !== null && t11 > EPS ? t11 : 0;
|
|
920
|
+
const mx = (a9.x + b11.x + c7.x) / 3 + time * (a9.bx + b11.bx + c7.bx) / 3;
|
|
921
|
+
const my = (a9.y + b11.y + c7.y) / 3 + time * (a9.by + b11.by + c7.by) / 3;
|
|
922
|
+
const nodeIdx = skeletonNodes.length;
|
|
923
|
+
skeletonNodes.push({ x: mx, y: my, height: time });
|
|
924
|
+
const aNodes = vertexToSkelNodes[a9.origIdx];
|
|
925
|
+
const bNodes = vertexToSkelNodes[b11.origIdx];
|
|
926
|
+
const cNodes = vertexToSkelNodes[c7.origIdx];
|
|
927
|
+
if (aNodes) aNodes.push(nodeIdx);
|
|
928
|
+
if (bNodes) bNodes.push(nodeIdx);
|
|
929
|
+
if (cNodes) cNodes.push(nodeIdx);
|
|
930
|
+
a9.active = false;
|
|
931
|
+
b11.active = false;
|
|
932
|
+
c7.active = false;
|
|
933
|
+
} else {
|
|
934
|
+
let cur = activeStart;
|
|
935
|
+
for (let i8 = 0; i8 < sz; i8++) {
|
|
936
|
+
cur.active = false;
|
|
937
|
+
cur = cur.next;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
const activeNodes = lavNodes.filter((nd) => nd.active);
|
|
943
|
+
const events = computeEvents(activeNodes);
|
|
944
|
+
if (events.length === 0) {
|
|
945
|
+
for (const nd of activeNodes) {
|
|
946
|
+
nd.active = false;
|
|
947
|
+
}
|
|
948
|
+
break;
|
|
949
|
+
}
|
|
950
|
+
const ev = events[0];
|
|
951
|
+
if (!ev) break;
|
|
952
|
+
if (ev.type === "edge") {
|
|
953
|
+
const a9 = ev.nodeA;
|
|
954
|
+
const b11 = ev.nodeB;
|
|
955
|
+
if (!a9.active || !b11.active) continue;
|
|
956
|
+
const nodeIdx = skeletonNodes.length;
|
|
957
|
+
skeletonNodes.push({ x: ev.x, y: ev.y, height: ev.time });
|
|
958
|
+
const aNodes = vertexToSkelNodes[a9.origIdx];
|
|
959
|
+
const bNodes = vertexToSkelNodes[b11.origIdx];
|
|
960
|
+
if (aNodes) aNodes.push(nodeIdx);
|
|
961
|
+
if (bNodes) bNodes.push(nodeIdx);
|
|
962
|
+
a9.x = ev.x;
|
|
963
|
+
a9.y = ev.y;
|
|
964
|
+
a9.next = b11.next;
|
|
965
|
+
b11.next.prev = a9;
|
|
966
|
+
b11.active = false;
|
|
967
|
+
const lavPoly = [];
|
|
968
|
+
let cur = a9;
|
|
969
|
+
do {
|
|
970
|
+
lavPoly.push({ x: cur.x, y: cur.y });
|
|
971
|
+
cur = cur.next;
|
|
972
|
+
} while (cur !== a9);
|
|
973
|
+
const bDir = bisector(lavPoly, 0);
|
|
974
|
+
a9.bx = bDir.dx;
|
|
975
|
+
a9.by = bDir.dy;
|
|
976
|
+
} else {
|
|
977
|
+
const a9 = ev.nodeA;
|
|
978
|
+
const b11 = ev.nodeB;
|
|
979
|
+
if (!a9.active || !b11.active) continue;
|
|
980
|
+
const nodeIdx = skeletonNodes.length;
|
|
981
|
+
skeletonNodes.push({ x: ev.x, y: ev.y, height: ev.time });
|
|
982
|
+
const aNodes = vertexToSkelNodes[a9.origIdx];
|
|
983
|
+
if (aNodes) aNodes.push(nodeIdx);
|
|
984
|
+
const bNodes = vertexToSkelNodes[b11.origIdx];
|
|
985
|
+
if (bNodes) bNodes.push(nodeIdx);
|
|
986
|
+
const aCopy = {
|
|
987
|
+
x: ev.x,
|
|
988
|
+
y: ev.y,
|
|
989
|
+
bx: 0,
|
|
990
|
+
by: 0,
|
|
991
|
+
origIdx: a9.origIdx,
|
|
992
|
+
prev: null,
|
|
993
|
+
next: null,
|
|
994
|
+
active: true
|
|
995
|
+
};
|
|
996
|
+
lavNodes.push(aCopy);
|
|
997
|
+
a9.x = ev.x;
|
|
998
|
+
a9.y = ev.y;
|
|
999
|
+
const aNext = a9.next;
|
|
1000
|
+
const bNext = b11.next;
|
|
1001
|
+
a9.next = bNext;
|
|
1002
|
+
bNext.prev = a9;
|
|
1003
|
+
aCopy.next = aNext;
|
|
1004
|
+
aNext.prev = aCopy;
|
|
1005
|
+
aCopy.prev = b11;
|
|
1006
|
+
b11.next = aCopy;
|
|
1007
|
+
const buildLavPoly = (start) => {
|
|
1008
|
+
const poly2 = [];
|
|
1009
|
+
let c7 = start;
|
|
1010
|
+
do {
|
|
1011
|
+
poly2.push({ x: c7.x, y: c7.y });
|
|
1012
|
+
c7 = c7.next;
|
|
1013
|
+
} while (c7 !== start);
|
|
1014
|
+
return poly2;
|
|
1015
|
+
};
|
|
1016
|
+
const lav1Poly = buildLavPoly(a9);
|
|
1017
|
+
const bDir1 = bisector(lav1Poly, 0);
|
|
1018
|
+
a9.bx = bDir1.dx;
|
|
1019
|
+
a9.by = bDir1.dy;
|
|
1020
|
+
const lav2Poly = buildLavPoly(aCopy);
|
|
1021
|
+
const bDir2 = bisector(lav2Poly, 0);
|
|
1022
|
+
aCopy.bx = bDir2.dx;
|
|
1023
|
+
aCopy.by = bDir2.dy;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
const faces = [];
|
|
1027
|
+
for (let i8 = 0; i8 < n7; i8++) {
|
|
1028
|
+
const j8 = (i8 + 1) % n7;
|
|
1029
|
+
const pi = polyAt(poly, i8);
|
|
1030
|
+
const pj = polyAt(poly, j8);
|
|
1031
|
+
const faceVerts = [pi, pj];
|
|
1032
|
+
const faceHeights = [0, 0];
|
|
1033
|
+
const jNodes = vertexToSkelNodes[j8];
|
|
1034
|
+
const iNodes = vertexToSkelNodes[i8];
|
|
1035
|
+
if (jNodes) {
|
|
1036
|
+
for (const ni of jNodes) {
|
|
1037
|
+
const sn = skeletonNodes[ni];
|
|
1038
|
+
if (sn) {
|
|
1039
|
+
faceVerts.push({ x: sn.x, y: sn.y });
|
|
1040
|
+
faceHeights.push(sn.height);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
if (iNodes) {
|
|
1045
|
+
for (let k10 = iNodes.length - 1; k10 >= 0; k10--) {
|
|
1046
|
+
const idx = iNodes[k10];
|
|
1047
|
+
if (idx === void 0) continue;
|
|
1048
|
+
const sn = skeletonNodes[idx];
|
|
1049
|
+
if (!sn) continue;
|
|
1050
|
+
const lastVert = faceVerts[faceVerts.length - 1];
|
|
1051
|
+
if (!lastVert) continue;
|
|
1052
|
+
const dist = len2(sn.x - lastVert.x, sn.y - lastVert.y);
|
|
1053
|
+
if (dist > EPS) {
|
|
1054
|
+
faceVerts.push({ x: sn.x, y: sn.y });
|
|
1055
|
+
faceHeights.push(sn.height);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
if (faceVerts.length >= 3) {
|
|
1060
|
+
faces.push({ vertices: faceVerts, heights: faceHeights });
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
const uniqueNodes = [];
|
|
1064
|
+
for (const sn of skeletonNodes) {
|
|
1065
|
+
const exists = uniqueNodes.some(
|
|
1066
|
+
(un) => Math.abs(un.x - sn.x) < 0.01 && Math.abs(un.y - sn.y) < 0.01
|
|
1067
|
+
);
|
|
1068
|
+
if (!exists) {
|
|
1069
|
+
uniqueNodes.push(sn);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
return { nodes: uniqueNodes, faces };
|
|
1073
|
+
}
|
|
1074
|
+
function extractPolygon(w7) {
|
|
1075
|
+
const edges = getEdges(w7);
|
|
1076
|
+
const pts = edges.map((e8) => {
|
|
1077
|
+
const pt = curveStartPoint(e8);
|
|
1078
|
+
return { x: pt[0], y: pt[1] };
|
|
1079
|
+
});
|
|
1080
|
+
const first = pts[0];
|
|
1081
|
+
const last = pts[pts.length - 1];
|
|
1082
|
+
if (pts.length > 1 && first && last && Math.abs(first.x - last.x) < 1e-10 && Math.abs(first.y - last.y) < 1e-10) {
|
|
1083
|
+
pts.pop();
|
|
1084
|
+
}
|
|
1085
|
+
return pts;
|
|
1086
|
+
}
|
|
1087
|
+
function fanTriangulate(count) {
|
|
1088
|
+
const tris = [];
|
|
1089
|
+
for (let i8 = 1; i8 < count - 1; i8++) {
|
|
1090
|
+
tris.push([0, i8, i8 + 1]);
|
|
1091
|
+
}
|
|
1092
|
+
return tris;
|
|
1093
|
+
}
|
|
1094
|
+
function buildTriFace$2(oc, a9, b11, c7) {
|
|
1095
|
+
const gpA = new oc.gp_Pnt_3(a9[0], a9[1], a9[2]);
|
|
1096
|
+
const gpB = new oc.gp_Pnt_3(b11[0], b11[1], b11[2]);
|
|
1097
|
+
const gpC = new oc.gp_Pnt_3(c7[0], c7[1], c7[2]);
|
|
1098
|
+
const e1 = new oc.BRepBuilderAPI_MakeEdge_3(gpA, gpB);
|
|
1099
|
+
const e22 = new oc.BRepBuilderAPI_MakeEdge_3(gpB, gpC);
|
|
1100
|
+
const e32 = new oc.BRepBuilderAPI_MakeEdge_3(gpC, gpA);
|
|
1101
|
+
const wireBuilder = new oc.BRepBuilderAPI_MakeWire_1();
|
|
1102
|
+
wireBuilder.Add_1(e1.Edge());
|
|
1103
|
+
wireBuilder.Add_1(e22.Edge());
|
|
1104
|
+
wireBuilder.Add_1(e32.Edge());
|
|
1105
|
+
let face2 = null;
|
|
1106
|
+
if (wireBuilder.IsDone()) {
|
|
1107
|
+
const makeFace2 = new oc.BRepBuilderAPI_MakeFace_15(wireBuilder.Wire(), false);
|
|
1108
|
+
if (makeFace2.IsDone()) {
|
|
1109
|
+
face2 = makeFace2.Face();
|
|
1110
|
+
}
|
|
1111
|
+
makeFace2.delete();
|
|
1112
|
+
}
|
|
1113
|
+
wireBuilder.delete();
|
|
1114
|
+
e1.delete();
|
|
1115
|
+
e22.delete();
|
|
1116
|
+
e32.delete();
|
|
1117
|
+
gpA.delete();
|
|
1118
|
+
gpB.delete();
|
|
1119
|
+
gpC.delete();
|
|
1120
|
+
return face2;
|
|
1121
|
+
}
|
|
1122
|
+
function roof(w7, options) {
|
|
1123
|
+
const angle = (options?.angle ?? 45) * (Math.PI / 180);
|
|
1124
|
+
const tanAngle = Math.tan(angle);
|
|
1125
|
+
try {
|
|
1126
|
+
const polygon2 = extractPolygon(w7);
|
|
1127
|
+
if (polygon2.length < 3) {
|
|
1128
|
+
return err(
|
|
1129
|
+
occtError(BrepErrorCode.ROOF_FAILED, "Wire must have at least 3 edges for roof generation")
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
const skeleton = computeStraightSkeleton(polygon2);
|
|
1133
|
+
if (skeleton.faces.length === 0) {
|
|
1134
|
+
return err(
|
|
1135
|
+
occtError(BrepErrorCode.ROOF_FAILED, "Straight skeleton computation produced no faces")
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
const oc = getKernel().oc;
|
|
1139
|
+
const sewing = new oc.BRepBuilderAPI_Sewing(1e-6, true, true, true, false);
|
|
1140
|
+
let faceCount = 0;
|
|
1141
|
+
try {
|
|
1142
|
+
for (const skFace of skeleton.faces) {
|
|
1143
|
+
const verts3d = skFace.vertices.map(
|
|
1144
|
+
(v7, i8) => [
|
|
1145
|
+
v7.x,
|
|
1146
|
+
v7.y,
|
|
1147
|
+
(skFace.heights[i8] ?? 0) * tanAngle
|
|
1148
|
+
]
|
|
1149
|
+
);
|
|
1150
|
+
const tris = fanTriangulate(verts3d.length);
|
|
1151
|
+
for (const [ai, bi, ci] of tris) {
|
|
1152
|
+
const va = verts3d[ai];
|
|
1153
|
+
const vb = verts3d[bi];
|
|
1154
|
+
const vc = verts3d[ci];
|
|
1155
|
+
if (!va || !vb || !vc) continue;
|
|
1156
|
+
const abx = vb[0] - va[0];
|
|
1157
|
+
const aby = vb[1] - va[1];
|
|
1158
|
+
const abz = vb[2] - va[2];
|
|
1159
|
+
const acx = vc[0] - va[0];
|
|
1160
|
+
const acy = vc[1] - va[1];
|
|
1161
|
+
const acz = vc[2] - va[2];
|
|
1162
|
+
const nx = aby * acz - abz * acy;
|
|
1163
|
+
const ny = abz * acx - abx * acz;
|
|
1164
|
+
const nz = abx * acy - aby * acx;
|
|
1165
|
+
const areaSq = nx * nx + ny * ny + nz * nz;
|
|
1166
|
+
if (areaSq < 1e-20) continue;
|
|
1167
|
+
const triFace = buildTriFace$2(oc, va, vb, vc);
|
|
1168
|
+
if (triFace !== null) {
|
|
1169
|
+
sewing.Add(triFace);
|
|
1170
|
+
faceCount++;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
const p0 = polygon2[0];
|
|
1175
|
+
if (p0) {
|
|
1176
|
+
for (let i8 = 1; i8 < polygon2.length - 1; i8++) {
|
|
1177
|
+
const pi = polygon2[i8];
|
|
1178
|
+
const pi1 = polygon2[i8 + 1];
|
|
1179
|
+
if (!pi || !pi1) continue;
|
|
1180
|
+
const va = [p0.x, p0.y, 0];
|
|
1181
|
+
const vb = [pi.x, pi.y, 0];
|
|
1182
|
+
const vc = [pi1.x, pi1.y, 0];
|
|
1183
|
+
const triFace = buildTriFace$2(oc, va, vc, vb);
|
|
1184
|
+
if (triFace !== null) {
|
|
1185
|
+
sewing.Add(triFace);
|
|
1186
|
+
faceCount++;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
if (faceCount === 0) {
|
|
1191
|
+
return err(
|
|
1192
|
+
occtError(BrepErrorCode.ROOF_FAILED, "No valid triangular faces could be built")
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
const progress = new oc.Message_ProgressRange_1();
|
|
1196
|
+
sewing.Perform(progress);
|
|
1197
|
+
progress.delete();
|
|
1198
|
+
const sewn = sewing.SewedShape();
|
|
1199
|
+
const fixer = new oc.ShapeFix_Solid_1();
|
|
1200
|
+
try {
|
|
1201
|
+
const shell2 = oc.TopoDS.Shell_1(sewn);
|
|
1202
|
+
const solid2 = fixer.SolidFromShell(shell2);
|
|
1203
|
+
const shapeFixer = new oc.ShapeFix_Shape_1(solid2);
|
|
1204
|
+
const shapeFixProgress = new oc.Message_ProgressRange_1();
|
|
1205
|
+
try {
|
|
1206
|
+
shapeFixer.Perform(shapeFixProgress);
|
|
1207
|
+
const fixed = shapeFixer.Shape();
|
|
1208
|
+
return ok(createSolid(fixed));
|
|
1209
|
+
} finally {
|
|
1210
|
+
shapeFixProgress.delete();
|
|
1211
|
+
shapeFixer.delete();
|
|
1212
|
+
}
|
|
1213
|
+
} catch {
|
|
1214
|
+
return ok(castShape(sewn));
|
|
1215
|
+
} finally {
|
|
1216
|
+
fixer.delete();
|
|
1217
|
+
}
|
|
1218
|
+
} finally {
|
|
1219
|
+
sewing.delete();
|
|
1220
|
+
}
|
|
1221
|
+
} catch (e8) {
|
|
1222
|
+
const msg = e8 instanceof Error ? e8.message : String(e8);
|
|
1223
|
+
return err(occtError(BrepErrorCode.ROOF_FAILED, `Roof generation failed: ${msg}`, e8));
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
function solveConstraints(nodes, constraints) {
|
|
1227
|
+
const transforms = /* @__PURE__ */ new Map();
|
|
1228
|
+
for (const node of nodes) {
|
|
1229
|
+
transforms.set(node, {
|
|
1230
|
+
position: [0, 0, 0],
|
|
1231
|
+
rotation: [1, 0, 0, 0]
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
for (const c7 of constraints) {
|
|
1235
|
+
if (c7.type === "coincident" && c7.entityA && c7.entityB) {
|
|
1236
|
+
const a9 = c7.entityA;
|
|
1237
|
+
const b11 = c7.entityB;
|
|
1238
|
+
if (a9.entity.type === "plane" && b11.entity.type === "plane") {
|
|
1239
|
+
const aNormal = a9.entity.normal ?? [0, 0, 1];
|
|
1240
|
+
const aOrigin = a9.entity.origin;
|
|
1241
|
+
const bOrigin = b11.entity.origin;
|
|
1242
|
+
const dot = aNormal[0] * (aOrigin[0] - bOrigin[0]) + aNormal[1] * (aOrigin[1] - bOrigin[1]) + aNormal[2] * (aOrigin[2] - bOrigin[2]);
|
|
1243
|
+
const pos = [dot * aNormal[0], dot * aNormal[1], dot * aNormal[2]];
|
|
1244
|
+
transforms.set(b11.node, { position: pos, rotation: [1, 0, 0, 0] });
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
if (c7.type === "distance" && c7.entityA && c7.entityB && c7.value !== void 0) {
|
|
1248
|
+
const a9 = c7.entityA;
|
|
1249
|
+
const b11 = c7.entityB;
|
|
1250
|
+
if (a9.entity.type === "plane" && b11.entity.type === "plane") {
|
|
1251
|
+
const aNormal = a9.entity.normal ?? [0, 0, 1];
|
|
1252
|
+
const aOrigin = a9.entity.origin;
|
|
1253
|
+
const bOrigin = b11.entity.origin;
|
|
1254
|
+
const currentDist = aNormal[0] * (aOrigin[0] - bOrigin[0]) + aNormal[1] * (aOrigin[1] - bOrigin[1]) + aNormal[2] * (aOrigin[2] - bOrigin[2]);
|
|
1255
|
+
const offset2 = currentDist + c7.value;
|
|
1256
|
+
const pos = [offset2 * aNormal[0], offset2 * aNormal[1], offset2 * aNormal[2]];
|
|
1257
|
+
transforms.set(b11.node, { position: pos, rotation: [1, 0, 0, 0] });
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
return { transforms, dof: 0, converged: true };
|
|
1262
|
+
}
|
|
1263
|
+
function extractEntity(mate) {
|
|
1264
|
+
if (mate.face) {
|
|
1265
|
+
const origin = faceCenter(mate.face);
|
|
1266
|
+
const normal = normalAt(mate.face);
|
|
1267
|
+
return { type: "plane", origin, normal };
|
|
1268
|
+
}
|
|
1269
|
+
if (mate.point) {
|
|
1270
|
+
return { type: "point", origin: mate.point };
|
|
1271
|
+
}
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
function addMate(assembly, constraint) {
|
|
1275
|
+
const existing = assembly.mates ?? [];
|
|
1276
|
+
return { ...assembly, mates: [...existing, constraint] };
|
|
1277
|
+
}
|
|
1278
|
+
function solveAssembly(assembly) {
|
|
1279
|
+
const mates = assembly.mates;
|
|
1280
|
+
if (!mates || mates.length === 0) {
|
|
1281
|
+
return err(
|
|
1282
|
+
validationError(BrepErrorCode.ASSEMBLY_MATE_INVALID, "solveAssembly: no mates defined")
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
try {
|
|
1286
|
+
const nodes = [];
|
|
1287
|
+
walkAssembly(assembly, (node) => {
|
|
1288
|
+
nodes.push(node.name);
|
|
1289
|
+
});
|
|
1290
|
+
const solverConstraints = [];
|
|
1291
|
+
for (const mate of mates) {
|
|
1292
|
+
if (mate.type === "fixed") {
|
|
1293
|
+
solverConstraints.push({
|
|
1294
|
+
type: "fixed",
|
|
1295
|
+
entityA: { node: mate.entity.node, entity: { type: "point", origin: [0, 0, 0] } }
|
|
1296
|
+
});
|
|
1297
|
+
continue;
|
|
1298
|
+
}
|
|
1299
|
+
if (mate.type === "coincident") {
|
|
1300
|
+
const entA = extractEntity(mate.entityA);
|
|
1301
|
+
const entB = extractEntity(mate.entityB);
|
|
1302
|
+
if (!entA || !entB) {
|
|
1303
|
+
return err(
|
|
1304
|
+
validationError(
|
|
1305
|
+
BrepErrorCode.ASSEMBLY_MATE_INVALID,
|
|
1306
|
+
"solveAssembly: could not extract geometry from mate entities"
|
|
1307
|
+
)
|
|
1308
|
+
);
|
|
1309
|
+
}
|
|
1310
|
+
solverConstraints.push({
|
|
1311
|
+
type: "coincident",
|
|
1312
|
+
entityA: { node: mate.entityA.node, entity: entA },
|
|
1313
|
+
entityB: { node: mate.entityB.node, entity: entB }
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
if (mate.type === "distance") {
|
|
1317
|
+
const entA = extractEntity(mate.entityA);
|
|
1318
|
+
const entB = extractEntity(mate.entityB);
|
|
1319
|
+
if (!entA || !entB) {
|
|
1320
|
+
return err(
|
|
1321
|
+
validationError(
|
|
1322
|
+
BrepErrorCode.ASSEMBLY_MATE_INVALID,
|
|
1323
|
+
"solveAssembly: could not extract geometry from mate entities"
|
|
1324
|
+
)
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
solverConstraints.push({
|
|
1328
|
+
type: "distance",
|
|
1329
|
+
entityA: { node: mate.entityA.node, entity: entA },
|
|
1330
|
+
entityB: { node: mate.entityB.node, entity: entB },
|
|
1331
|
+
value: mate.distance
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
if (mate.type === "angle") {
|
|
1335
|
+
const entA = extractEntity(mate.entityA);
|
|
1336
|
+
const entB = extractEntity(mate.entityB);
|
|
1337
|
+
if (!entA || !entB) {
|
|
1338
|
+
return err(
|
|
1339
|
+
validationError(
|
|
1340
|
+
BrepErrorCode.ASSEMBLY_MATE_INVALID,
|
|
1341
|
+
"solveAssembly: could not extract geometry from mate entities"
|
|
1342
|
+
)
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
solverConstraints.push({
|
|
1346
|
+
type: "angle",
|
|
1347
|
+
entityA: { node: mate.entityA.node, entity: entA },
|
|
1348
|
+
entityB: { node: mate.entityB.node, entity: entB },
|
|
1349
|
+
value: mate.angle
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
if (mate.type === "concentric") {
|
|
1353
|
+
const entA = extractEntity(mate.axisA);
|
|
1354
|
+
const entB = extractEntity(mate.axisB);
|
|
1355
|
+
if (!entA || !entB) {
|
|
1356
|
+
return err(
|
|
1357
|
+
validationError(
|
|
1358
|
+
BrepErrorCode.ASSEMBLY_MATE_INVALID,
|
|
1359
|
+
"solveAssembly: could not extract geometry from mate entities"
|
|
1360
|
+
)
|
|
1361
|
+
);
|
|
1362
|
+
}
|
|
1363
|
+
solverConstraints.push({
|
|
1364
|
+
type: "concentric",
|
|
1365
|
+
entityA: { node: mate.axisA.node, entity: entA },
|
|
1366
|
+
entityB: { node: mate.axisB.node, entity: entB }
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
const result = solveConstraints(nodes, solverConstraints);
|
|
1371
|
+
if (!result.converged) ;
|
|
1372
|
+
return ok({
|
|
1373
|
+
transforms: result.transforms,
|
|
1374
|
+
dof: result.dof,
|
|
1375
|
+
converged: result.converged
|
|
1376
|
+
});
|
|
1377
|
+
} catch (e8) {
|
|
1378
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
1379
|
+
return err(occtError(BrepErrorCode.ASSEMBLY_SOLVE_FAILED, `Assembly solve failed: ${raw}`, e8));
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
326
1382
|
function checkInterference(shape1, shape2, tolerance = 1e-6) {
|
|
327
1383
|
if (shape1.wrapped.IsNull()) {
|
|
328
1384
|
return err(
|
|
@@ -350,29 +1406,481 @@ function checkInterference(shape1, shape2, tolerance = 1e-6) {
|
|
|
350
1406
|
}
|
|
351
1407
|
function checkAllInterferences(shapes, tolerance = 1e-6) {
|
|
352
1408
|
const pairs = [];
|
|
353
|
-
shapes.forEach((si,
|
|
354
|
-
for (let
|
|
355
|
-
const result = unwrap(checkInterference(si, shapes[
|
|
1409
|
+
shapes.forEach((si, i8) => {
|
|
1410
|
+
for (let j8 = i8 + 1; j8 < shapes.length; j8++) {
|
|
1411
|
+
const result = unwrap(checkInterference(si, shapes[j8], tolerance));
|
|
356
1412
|
if (result.hasInterference) {
|
|
357
|
-
pairs.push({ i:
|
|
1413
|
+
pairs.push({ i: i8, j: j8, result });
|
|
358
1414
|
}
|
|
359
1415
|
}
|
|
360
1416
|
});
|
|
361
1417
|
return pairs;
|
|
362
1418
|
}
|
|
363
|
-
function
|
|
364
|
-
|
|
365
|
-
|
|
1419
|
+
function parseEntities(text) {
|
|
1420
|
+
const lines = text.split(/\r?\n/);
|
|
1421
|
+
const entities = [];
|
|
1422
|
+
let inEntities = false;
|
|
1423
|
+
let current;
|
|
1424
|
+
for (let i8 = 0; i8 < lines.length - 1; i8 += 2) {
|
|
1425
|
+
const codeLine = lines[i8];
|
|
1426
|
+
const valueLine = lines[i8 + 1];
|
|
1427
|
+
if (codeLine === void 0 || valueLine === void 0) continue;
|
|
1428
|
+
const code = parseInt(codeLine.trim(), 10);
|
|
1429
|
+
const value = valueLine.trim();
|
|
1430
|
+
if (isNaN(code)) continue;
|
|
1431
|
+
if (code === 2 && value === "ENTITIES") {
|
|
1432
|
+
inEntities = true;
|
|
1433
|
+
continue;
|
|
1434
|
+
}
|
|
1435
|
+
if (!inEntities) continue;
|
|
1436
|
+
if (code === 0) {
|
|
1437
|
+
if (value === "ENDSEC" || value === "EOF") {
|
|
1438
|
+
if (current) entities.push(current);
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
if (current) entities.push(current);
|
|
1442
|
+
current = { type: value, layer: "0", data: /* @__PURE__ */ new Map() };
|
|
1443
|
+
continue;
|
|
1444
|
+
}
|
|
1445
|
+
if (current) {
|
|
1446
|
+
if (code === 8) {
|
|
1447
|
+
current.layer = value;
|
|
1448
|
+
} else {
|
|
1449
|
+
current.data.set(code, value);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
return entities;
|
|
1454
|
+
}
|
|
1455
|
+
function getNum(data, code, fallback = 0) {
|
|
1456
|
+
const v7 = data.get(code);
|
|
1457
|
+
if (v7 === void 0) return fallback;
|
|
1458
|
+
const n7 = parseFloat(v7);
|
|
1459
|
+
return isNaN(n7) ? fallback : n7;
|
|
1460
|
+
}
|
|
1461
|
+
function entityToEdge(entity, oc) {
|
|
1462
|
+
const { type, data } = entity;
|
|
1463
|
+
if (type === "LINE") {
|
|
1464
|
+
const p1 = new oc.gp_Pnt_3(getNum(data, 10), getNum(data, 20), getNum(data, 30));
|
|
1465
|
+
const p22 = new oc.gp_Pnt_3(getNum(data, 11), getNum(data, 21), getNum(data, 31));
|
|
1466
|
+
try {
|
|
1467
|
+
const builder = new oc.BRepBuilderAPI_MakeEdge_3(p1, p22);
|
|
1468
|
+
const edge = builder.Edge();
|
|
1469
|
+
builder.delete();
|
|
1470
|
+
return edge;
|
|
1471
|
+
} finally {
|
|
1472
|
+
p1.delete();
|
|
1473
|
+
p22.delete();
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
if (type === "CIRCLE") {
|
|
1477
|
+
const cx = getNum(data, 10);
|
|
1478
|
+
const cy = getNum(data, 20);
|
|
1479
|
+
const cz = getNum(data, 30);
|
|
1480
|
+
const radius = getNum(data, 40);
|
|
1481
|
+
const center = new oc.gp_Pnt_3(cx, cy, cz);
|
|
1482
|
+
const dir = new oc.gp_Dir_4(0, 0, 1);
|
|
1483
|
+
const ax2 = new oc.gp_Ax2_3(center, dir);
|
|
1484
|
+
const circ = new oc.gp_Circ_2(ax2, radius);
|
|
1485
|
+
try {
|
|
1486
|
+
const builder = new oc.BRepBuilderAPI_MakeEdge_8(circ);
|
|
1487
|
+
const edge = builder.Edge();
|
|
1488
|
+
builder.delete();
|
|
1489
|
+
return edge;
|
|
1490
|
+
} finally {
|
|
1491
|
+
center.delete();
|
|
1492
|
+
dir.delete();
|
|
1493
|
+
ax2.delete();
|
|
1494
|
+
circ.delete();
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (type === "ARC") {
|
|
1498
|
+
const cx = getNum(data, 10);
|
|
1499
|
+
const cy = getNum(data, 20);
|
|
1500
|
+
const cz = getNum(data, 30);
|
|
1501
|
+
const radius = getNum(data, 40);
|
|
1502
|
+
const startAngleDeg = getNum(data, 50);
|
|
1503
|
+
const endAngleDeg = getNum(data, 51);
|
|
1504
|
+
const startAngle = startAngleDeg * Math.PI / 180;
|
|
1505
|
+
const endAngle = endAngleDeg * Math.PI / 180;
|
|
1506
|
+
const center = new oc.gp_Pnt_3(cx, cy, cz);
|
|
1507
|
+
const dir = new oc.gp_Dir_4(0, 0, 1);
|
|
1508
|
+
const ax2 = new oc.gp_Ax2_3(center, dir);
|
|
1509
|
+
const circ = new oc.gp_Circ_2(ax2, radius);
|
|
1510
|
+
try {
|
|
1511
|
+
const builder = new oc.BRepBuilderAPI_MakeEdge_9(circ, startAngle, endAngle);
|
|
1512
|
+
const edge = builder.Edge();
|
|
1513
|
+
builder.delete();
|
|
1514
|
+
return edge;
|
|
1515
|
+
} finally {
|
|
1516
|
+
center.delete();
|
|
1517
|
+
dir.delete();
|
|
1518
|
+
ax2.delete();
|
|
1519
|
+
circ.delete();
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
return void 0;
|
|
1523
|
+
}
|
|
1524
|
+
async function importDXF(blob, options) {
|
|
1525
|
+
const oc = getKernel().oc;
|
|
1526
|
+
let text;
|
|
1527
|
+
try {
|
|
1528
|
+
text = await blob.text();
|
|
1529
|
+
} catch (cause) {
|
|
1530
|
+
return err(ioError(BrepErrorCode.DXF_IMPORT_FAILED, "Failed to read DXF blob", cause));
|
|
1531
|
+
}
|
|
1532
|
+
const allEntities = parseEntities(text);
|
|
1533
|
+
const entities = options?.layer !== void 0 ? allEntities.filter((e8) => e8.layer === options.layer) : allEntities;
|
|
1534
|
+
if (entities.length === 0) {
|
|
1535
|
+
return ok([]);
|
|
1536
|
+
}
|
|
1537
|
+
const edges = [];
|
|
1538
|
+
try {
|
|
1539
|
+
for (const entity of entities) {
|
|
1540
|
+
const edge = entityToEdge(entity, oc);
|
|
1541
|
+
if (edge !== void 0) {
|
|
1542
|
+
edges.push(edge);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
if (edges.length === 0) {
|
|
1546
|
+
return ok([]);
|
|
1547
|
+
}
|
|
1548
|
+
const wireBuilder = new oc.BRepBuilderAPI_MakeWire_1();
|
|
1549
|
+
try {
|
|
1550
|
+
for (const edge of edges) {
|
|
1551
|
+
wireBuilder.Add_1(edge);
|
|
1552
|
+
}
|
|
1553
|
+
if (wireBuilder.IsDone()) {
|
|
1554
|
+
const wire2 = wireBuilder.Wire();
|
|
1555
|
+
return ok([createWire(wire2)]);
|
|
1556
|
+
}
|
|
1557
|
+
return err(
|
|
1558
|
+
ioError(BrepErrorCode.DXF_IMPORT_FAILED, "Failed to assemble DXF edges into a wire")
|
|
1559
|
+
);
|
|
1560
|
+
} finally {
|
|
1561
|
+
wireBuilder.delete();
|
|
1562
|
+
}
|
|
1563
|
+
} catch (cause) {
|
|
1564
|
+
return err(
|
|
1565
|
+
ioError(BrepErrorCode.DXF_IMPORT_FAILED, "Failed to convert DXF entities to geometry", cause)
|
|
1566
|
+
);
|
|
1567
|
+
} finally {
|
|
1568
|
+
for (const edge of edges) {
|
|
1569
|
+
edge.delete();
|
|
1570
|
+
}
|
|
366
1571
|
}
|
|
367
|
-
return s5;
|
|
368
1572
|
}
|
|
369
|
-
function
|
|
370
|
-
|
|
1573
|
+
async function importOBJ(blob) {
|
|
1574
|
+
const text = await blob.text();
|
|
1575
|
+
const lines = text.split("\n");
|
|
1576
|
+
const vertices = [];
|
|
1577
|
+
const faces = [];
|
|
1578
|
+
for (const raw of lines) {
|
|
1579
|
+
const line2 = raw.trim();
|
|
1580
|
+
if (line2.startsWith("v ")) {
|
|
1581
|
+
const parts = line2.split(/\s+/);
|
|
1582
|
+
const x4 = parseFloat(parts[1] ?? "");
|
|
1583
|
+
const y5 = parseFloat(parts[2] ?? "");
|
|
1584
|
+
const z6 = parseFloat(parts[3] ?? "");
|
|
1585
|
+
if (isNaN(x4) || isNaN(y5) || isNaN(z6)) continue;
|
|
1586
|
+
vertices.push([x4, y5, z6]);
|
|
1587
|
+
} else if (line2.startsWith("f ")) {
|
|
1588
|
+
const parts = line2.split(/\s+/).slice(1);
|
|
1589
|
+
const indices = [];
|
|
1590
|
+
for (const p8 of parts) {
|
|
1591
|
+
const idx = parseInt(p8.split("/")[0] ?? "", 10);
|
|
1592
|
+
if (!isNaN(idx)) indices.push(idx);
|
|
1593
|
+
}
|
|
1594
|
+
if (indices.length >= 3) faces.push(indices);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
if (vertices.length === 0 || faces.length === 0) {
|
|
1598
|
+
return err(ioError(BrepErrorCode.OBJ_IMPORT_FAILED, "OBJ file contains no valid geometry"));
|
|
1599
|
+
}
|
|
1600
|
+
try {
|
|
1601
|
+
return buildSolidFromMesh$1(vertices, faces);
|
|
1602
|
+
} catch (e8) {
|
|
1603
|
+
const msg = e8 instanceof Error ? e8.message : String(e8);
|
|
1604
|
+
return err(ioError(BrepErrorCode.OBJ_IMPORT_FAILED, `OBJ import failed: ${msg}`, e8));
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
function buildSolidFromMesh$1(vertices, faces) {
|
|
1608
|
+
const oc = getKernel().oc;
|
|
1609
|
+
const sewing = new oc.BRepBuilderAPI_Sewing(1e-6, true, true, true, false);
|
|
1610
|
+
let faceCount = 0;
|
|
1611
|
+
try {
|
|
1612
|
+
for (const face2 of faces) {
|
|
1613
|
+
for (let i8 = 1; i8 < face2.length - 1; i8++) {
|
|
1614
|
+
const rawA = face2[0] ?? 0;
|
|
1615
|
+
const rawB = face2[i8] ?? 0;
|
|
1616
|
+
const rawC = face2[i8 + 1] ?? 0;
|
|
1617
|
+
const ai = rawA > 0 ? rawA - 1 : vertices.length + rawA;
|
|
1618
|
+
const bi = rawB > 0 ? rawB - 1 : vertices.length + rawB;
|
|
1619
|
+
const ci = rawC > 0 ? rawC - 1 : vertices.length + rawC;
|
|
1620
|
+
const va = vertices[ai];
|
|
1621
|
+
const vb = vertices[bi];
|
|
1622
|
+
const vc = vertices[ci];
|
|
1623
|
+
if (!va || !vb || !vc) continue;
|
|
1624
|
+
const triFace = buildTriFace$1(oc, va, vb, vc);
|
|
1625
|
+
if (triFace !== null) {
|
|
1626
|
+
sewing.Add(triFace);
|
|
1627
|
+
faceCount++;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
if (faceCount === 0) {
|
|
1632
|
+
return err(
|
|
1633
|
+
ioError(BrepErrorCode.OBJ_IMPORT_FAILED, "No valid triangular faces could be built")
|
|
1634
|
+
);
|
|
1635
|
+
}
|
|
1636
|
+
const progress = new oc.Message_ProgressRange_1();
|
|
1637
|
+
sewing.Perform(progress);
|
|
1638
|
+
progress.delete();
|
|
1639
|
+
const sewn = sewing.SewedShape();
|
|
1640
|
+
const fixer = new oc.ShapeFix_Solid_1();
|
|
1641
|
+
try {
|
|
1642
|
+
const shell2 = oc.TopoDS.Shell_1(sewn);
|
|
1643
|
+
const solid2 = fixer.SolidFromShell(shell2);
|
|
1644
|
+
return ok(castShape(solid2));
|
|
1645
|
+
} catch {
|
|
1646
|
+
return ok(castShape(sewn));
|
|
1647
|
+
} finally {
|
|
1648
|
+
fixer.delete();
|
|
1649
|
+
}
|
|
1650
|
+
} finally {
|
|
1651
|
+
sewing.delete();
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
function buildTriFace$1(oc, a9, b11, c7) {
|
|
1655
|
+
const gpA = new oc.gp_Pnt_3(a9[0], a9[1], a9[2]);
|
|
1656
|
+
const gpB = new oc.gp_Pnt_3(b11[0], b11[1], b11[2]);
|
|
1657
|
+
const gpC = new oc.gp_Pnt_3(c7[0], c7[1], c7[2]);
|
|
1658
|
+
const e1 = new oc.BRepBuilderAPI_MakeEdge_3(gpA, gpB);
|
|
1659
|
+
const e22 = new oc.BRepBuilderAPI_MakeEdge_3(gpB, gpC);
|
|
1660
|
+
const e32 = new oc.BRepBuilderAPI_MakeEdge_3(gpC, gpA);
|
|
1661
|
+
const wireBuilder = new oc.BRepBuilderAPI_MakeWire_1();
|
|
1662
|
+
wireBuilder.Add_1(e1.Edge());
|
|
1663
|
+
wireBuilder.Add_1(e22.Edge());
|
|
1664
|
+
wireBuilder.Add_1(e32.Edge());
|
|
1665
|
+
let face2 = null;
|
|
1666
|
+
if (wireBuilder.IsDone()) {
|
|
1667
|
+
const makeFace2 = new oc.BRepBuilderAPI_MakeFace_15(wireBuilder.Wire(), false);
|
|
1668
|
+
if (makeFace2.IsDone()) {
|
|
1669
|
+
face2 = makeFace2.Face();
|
|
1670
|
+
}
|
|
1671
|
+
makeFace2.delete();
|
|
1672
|
+
}
|
|
1673
|
+
wireBuilder.delete();
|
|
1674
|
+
e1.delete();
|
|
1675
|
+
e22.delete();
|
|
1676
|
+
e32.delete();
|
|
1677
|
+
gpA.delete();
|
|
1678
|
+
gpB.delete();
|
|
1679
|
+
gpC.delete();
|
|
1680
|
+
return face2;
|
|
1681
|
+
}
|
|
1682
|
+
function extractFromZip(data, target) {
|
|
1683
|
+
let eocdOffset = -1;
|
|
1684
|
+
for (let i8 = data.length - 22; i8 >= 0; i8--) {
|
|
1685
|
+
if (data[i8] === 80 && data[i8 + 1] === 75 && data[i8 + 2] === 5 && data[i8 + 3] === 6) {
|
|
1686
|
+
eocdOffset = i8;
|
|
1687
|
+
break;
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
if (eocdOffset < 0) return null;
|
|
1691
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
1692
|
+
const cdOffset = view.getUint32(eocdOffset + 16, true);
|
|
1693
|
+
const cdSize = view.getUint32(eocdOffset + 12, true);
|
|
1694
|
+
const cdEnd = cdOffset + cdSize;
|
|
1695
|
+
let pos = cdOffset;
|
|
1696
|
+
const decoder = new TextDecoder();
|
|
1697
|
+
while (pos < cdEnd) {
|
|
1698
|
+
const sig = view.getUint32(pos, true);
|
|
1699
|
+
if (sig !== 33639248) break;
|
|
1700
|
+
const nameLen = view.getUint16(pos + 28, true);
|
|
1701
|
+
const extraLen = view.getUint16(pos + 30, true);
|
|
1702
|
+
const commentLen = view.getUint16(pos + 32, true);
|
|
1703
|
+
const localOffset = view.getUint32(pos + 42, true);
|
|
1704
|
+
const name = decoder.decode(data.subarray(pos + 46, pos + 46 + nameLen));
|
|
1705
|
+
if (name === target) {
|
|
1706
|
+
const compressionMethod = view.getUint16(localOffset + 8, true);
|
|
1707
|
+
if (compressionMethod !== 0) {
|
|
1708
|
+
return null;
|
|
1709
|
+
}
|
|
1710
|
+
const localNameLen = view.getUint16(localOffset + 26, true);
|
|
1711
|
+
const localExtraLen = view.getUint16(localOffset + 28, true);
|
|
1712
|
+
const compressedSize = view.getUint32(localOffset + 18, true);
|
|
1713
|
+
const dataStart = localOffset + 30 + localNameLen + localExtraLen;
|
|
1714
|
+
return data.subarray(dataStart, dataStart + compressedSize);
|
|
1715
|
+
}
|
|
1716
|
+
pos += 46 + nameLen + extraLen + commentLen;
|
|
1717
|
+
}
|
|
1718
|
+
return null;
|
|
1719
|
+
}
|
|
1720
|
+
function isAttrChar(code) {
|
|
1721
|
+
return code >= 97 && code <= 122 || // a-z
|
|
1722
|
+
code >= 65 && code <= 90 || // A-Z
|
|
1723
|
+
code >= 48 && code <= 57 || // 0-9
|
|
1724
|
+
code === 95;
|
|
1725
|
+
}
|
|
1726
|
+
function parseTagAttrs(tag) {
|
|
1727
|
+
const attrs = {};
|
|
1728
|
+
let pos = 0;
|
|
1729
|
+
while (pos < tag.length) {
|
|
1730
|
+
const eq = tag.indexOf('="', pos);
|
|
1731
|
+
if (eq < 0) break;
|
|
1732
|
+
let nameStart = eq;
|
|
1733
|
+
while (nameStart > 0 && isAttrChar(tag.charCodeAt(nameStart - 1))) nameStart--;
|
|
1734
|
+
if (nameStart === eq) {
|
|
1735
|
+
pos = eq + 2;
|
|
1736
|
+
continue;
|
|
1737
|
+
}
|
|
1738
|
+
const name = tag.slice(nameStart, eq);
|
|
1739
|
+
const valStart = eq + 2;
|
|
1740
|
+
const closeQuote = tag.indexOf('"', valStart);
|
|
1741
|
+
if (closeQuote < 0) break;
|
|
1742
|
+
attrs[name] = tag.slice(valStart, closeQuote);
|
|
1743
|
+
pos = closeQuote + 1;
|
|
1744
|
+
}
|
|
1745
|
+
return attrs;
|
|
1746
|
+
}
|
|
1747
|
+
function findTags(xml, tagName) {
|
|
1748
|
+
const tags = [];
|
|
1749
|
+
const needle = `<${tagName} `;
|
|
1750
|
+
let pos = 0;
|
|
1751
|
+
while (pos < xml.length) {
|
|
1752
|
+
const start = xml.indexOf(needle, pos);
|
|
1753
|
+
if (start < 0) break;
|
|
1754
|
+
const end = xml.indexOf(">", start);
|
|
1755
|
+
if (end < 0) break;
|
|
1756
|
+
tags.push(xml.slice(start, end + 1));
|
|
1757
|
+
pos = end + 1;
|
|
1758
|
+
}
|
|
1759
|
+
return tags;
|
|
1760
|
+
}
|
|
1761
|
+
function parseModelXml(xml) {
|
|
1762
|
+
const vertices = [];
|
|
1763
|
+
const triangles = [];
|
|
1764
|
+
for (const tag of findTags(xml, "vertex")) {
|
|
1765
|
+
const a9 = parseTagAttrs(tag);
|
|
1766
|
+
if (a9["x"] !== void 0 && a9["y"] !== void 0 && a9["z"] !== void 0) {
|
|
1767
|
+
vertices.push([parseFloat(a9["x"]), parseFloat(a9["y"]), parseFloat(a9["z"])]);
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
for (const tag of findTags(xml, "triangle")) {
|
|
1771
|
+
const a9 = parseTagAttrs(tag);
|
|
1772
|
+
if (a9["v1"] !== void 0 && a9["v2"] !== void 0 && a9["v3"] !== void 0) {
|
|
1773
|
+
triangles.push([parseInt(a9["v1"], 10), parseInt(a9["v2"], 10), parseInt(a9["v3"], 10)]);
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
return { vertices, triangles };
|
|
1777
|
+
}
|
|
1778
|
+
function buildTriFace(oc, a9, b11, c7) {
|
|
1779
|
+
const gpA = new oc.gp_Pnt_3(a9[0], a9[1], a9[2]);
|
|
1780
|
+
const gpB = new oc.gp_Pnt_3(b11[0], b11[1], b11[2]);
|
|
1781
|
+
const gpC = new oc.gp_Pnt_3(c7[0], c7[1], c7[2]);
|
|
1782
|
+
const e1 = new oc.BRepBuilderAPI_MakeEdge_3(gpA, gpB);
|
|
1783
|
+
const e22 = new oc.BRepBuilderAPI_MakeEdge_3(gpB, gpC);
|
|
1784
|
+
const e32 = new oc.BRepBuilderAPI_MakeEdge_3(gpC, gpA);
|
|
1785
|
+
const wireBuilder = new oc.BRepBuilderAPI_MakeWire_1();
|
|
1786
|
+
wireBuilder.Add_1(e1.Edge());
|
|
1787
|
+
wireBuilder.Add_1(e22.Edge());
|
|
1788
|
+
wireBuilder.Add_1(e32.Edge());
|
|
1789
|
+
let face2 = null;
|
|
1790
|
+
if (wireBuilder.IsDone()) {
|
|
1791
|
+
const makeFace2 = new oc.BRepBuilderAPI_MakeFace_15(wireBuilder.Wire(), false);
|
|
1792
|
+
if (makeFace2.IsDone()) {
|
|
1793
|
+
face2 = makeFace2.Face();
|
|
1794
|
+
}
|
|
1795
|
+
makeFace2.delete();
|
|
1796
|
+
}
|
|
1797
|
+
wireBuilder.delete();
|
|
1798
|
+
e1.delete();
|
|
1799
|
+
e22.delete();
|
|
1800
|
+
e32.delete();
|
|
1801
|
+
gpA.delete();
|
|
1802
|
+
gpB.delete();
|
|
1803
|
+
gpC.delete();
|
|
1804
|
+
return face2;
|
|
1805
|
+
}
|
|
1806
|
+
function buildSolidFromMesh(mesh2) {
|
|
1807
|
+
const oc = getKernel().oc;
|
|
1808
|
+
const sewing = new oc.BRepBuilderAPI_Sewing(1e-6, true, true, true, false);
|
|
1809
|
+
let faceCount = 0;
|
|
1810
|
+
try {
|
|
1811
|
+
for (const [v1, v22, v32] of mesh2.triangles) {
|
|
1812
|
+
const va = mesh2.vertices[v1];
|
|
1813
|
+
const vb = mesh2.vertices[v22];
|
|
1814
|
+
const vc = mesh2.vertices[v32];
|
|
1815
|
+
if (!va || !vb || !vc) continue;
|
|
1816
|
+
const triFace = buildTriFace(oc, va, vb, vc);
|
|
1817
|
+
if (triFace !== null) {
|
|
1818
|
+
sewing.Add(triFace);
|
|
1819
|
+
faceCount++;
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
if (faceCount === 0) {
|
|
1823
|
+
return err(
|
|
1824
|
+
ioError(BrepErrorCode.THREEMF_IMPORT_FAILED, "No valid triangular faces could be built")
|
|
1825
|
+
);
|
|
1826
|
+
}
|
|
1827
|
+
const progress = new oc.Message_ProgressRange_1();
|
|
1828
|
+
sewing.Perform(progress);
|
|
1829
|
+
progress.delete();
|
|
1830
|
+
const sewn = sewing.SewedShape();
|
|
1831
|
+
const fixer = new oc.ShapeFix_Solid_1();
|
|
1832
|
+
try {
|
|
1833
|
+
const shell2 = oc.TopoDS.Shell_1(sewn);
|
|
1834
|
+
const solid2 = fixer.SolidFromShell(shell2);
|
|
1835
|
+
return ok(castShape(solid2));
|
|
1836
|
+
} catch {
|
|
1837
|
+
return ok(castShape(sewn));
|
|
1838
|
+
} finally {
|
|
1839
|
+
fixer.delete();
|
|
1840
|
+
}
|
|
1841
|
+
} finally {
|
|
1842
|
+
sewing.delete();
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
async function importThreeMF(blob) {
|
|
1846
|
+
try {
|
|
1847
|
+
const arrayBuf = await blob.arrayBuffer();
|
|
1848
|
+
const data = new Uint8Array(arrayBuf);
|
|
1849
|
+
const modelData = extractFromZip(data, "3D/3dmodel.model");
|
|
1850
|
+
if (!modelData) {
|
|
1851
|
+
return err(
|
|
1852
|
+
ioError(
|
|
1853
|
+
BrepErrorCode.THREEMF_IMPORT_FAILED,
|
|
1854
|
+
"3MF archive does not contain 3D/3dmodel.model (or uses unsupported compression)"
|
|
1855
|
+
)
|
|
1856
|
+
);
|
|
1857
|
+
}
|
|
1858
|
+
const xml = new TextDecoder().decode(modelData);
|
|
1859
|
+
const parsed = parseModelXml(xml);
|
|
1860
|
+
if (parsed.vertices.length === 0 || parsed.triangles.length === 0) {
|
|
1861
|
+
return err(
|
|
1862
|
+
ioError(BrepErrorCode.THREEMF_IMPORT_FAILED, "3MF model contains no valid geometry")
|
|
1863
|
+
);
|
|
1864
|
+
}
|
|
1865
|
+
return buildSolidFromMesh(parsed);
|
|
1866
|
+
} catch (e8) {
|
|
1867
|
+
const msg = e8 instanceof Error ? e8.message : String(e8);
|
|
1868
|
+
return err(ioError(BrepErrorCode.THREEMF_IMPORT_FAILED, `3MF import failed: ${msg}`, e8));
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
function resolve(s6) {
|
|
1872
|
+
if ("__wrapped" in s6) {
|
|
1873
|
+
return s6.val;
|
|
1874
|
+
}
|
|
1875
|
+
return s6;
|
|
1876
|
+
}
|
|
1877
|
+
function resolve3D(s6) {
|
|
1878
|
+
return resolve(s6);
|
|
371
1879
|
}
|
|
372
1880
|
function box(width, depth, height, options) {
|
|
373
1881
|
const oc = getKernel().oc;
|
|
374
|
-
const
|
|
375
|
-
const maker =
|
|
1882
|
+
const r11 = gcWithScope();
|
|
1883
|
+
const maker = r11(new oc.BRepPrimAPI_MakeBox_2(width, depth, height));
|
|
376
1884
|
const solid2 = createSolid(maker.Solid());
|
|
377
1885
|
const center = options?.at ?? (options?.centered ? [0, 0, 0] : void 0);
|
|
378
1886
|
if (center) {
|
|
@@ -473,14 +1981,14 @@ function tangentArc(startPoint, startTgt, endPoint) {
|
|
|
473
1981
|
function wire(listOfEdges) {
|
|
474
1982
|
return assembleWire(listOfEdges);
|
|
475
1983
|
}
|
|
476
|
-
function face(
|
|
477
|
-
return makeFace(
|
|
1984
|
+
function face(w7, holes) {
|
|
1985
|
+
return makeFace(w7, holes);
|
|
478
1986
|
}
|
|
479
|
-
function filledFace(
|
|
480
|
-
return makeNonPlanarFace(
|
|
1987
|
+
function filledFace(w7) {
|
|
1988
|
+
return makeNonPlanarFace(w7);
|
|
481
1989
|
}
|
|
482
|
-
function subFace(originFace,
|
|
483
|
-
return makeNewFaceWithinFace(originFace,
|
|
1990
|
+
function subFace(originFace, w7) {
|
|
1991
|
+
return makeNewFaceWithinFace(originFace, w7);
|
|
484
1992
|
}
|
|
485
1993
|
function polygon(points) {
|
|
486
1994
|
return makePolygon(points);
|
|
@@ -494,14 +2002,14 @@ function compound(shapeArray) {
|
|
|
494
2002
|
function solid(facesOrShells) {
|
|
495
2003
|
return makeSolid(facesOrShells);
|
|
496
2004
|
}
|
|
497
|
-
function offsetFace(
|
|
498
|
-
return makeOffset(
|
|
2005
|
+
function offsetFace(f12, distance, tolerance) {
|
|
2006
|
+
return makeOffset(f12, distance, tolerance);
|
|
499
2007
|
}
|
|
500
2008
|
function sewShells(facesOrShells, ignoreType) {
|
|
501
2009
|
return weldShellsAndFaces(facesOrShells, ignoreType);
|
|
502
2010
|
}
|
|
503
|
-
function addHoles(
|
|
504
|
-
return addHolesInFace(
|
|
2011
|
+
function addHoles(f12, holes) {
|
|
2012
|
+
return addHolesInFace(f12, holes);
|
|
505
2013
|
}
|
|
506
2014
|
function validateNotNull(shape2, label) {
|
|
507
2015
|
if (shape2.wrapped.IsNull()) {
|
|
@@ -514,18 +2022,20 @@ function thicken$1(shape2, thickness) {
|
|
|
514
2022
|
if (isErr(check)) return check;
|
|
515
2023
|
try {
|
|
516
2024
|
const oc = getKernel().oc;
|
|
517
|
-
const
|
|
518
|
-
const builder =
|
|
2025
|
+
const r11 = gcWithScope();
|
|
2026
|
+
const builder = r11(new oc.BRepOffsetAPI_MakeThickSolid());
|
|
519
2027
|
builder.MakeThickSolidBySimple(shape2.wrapped, thickness);
|
|
520
|
-
const progress =
|
|
2028
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
521
2029
|
builder.Build(progress);
|
|
522
2030
|
const resultOc = builder.Shape();
|
|
523
2031
|
const cast = castShape(resultOc);
|
|
524
2032
|
propagateOrigins(builder, [shape2], cast);
|
|
2033
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2034
|
+
propagateColors(builder, [shape2], cast);
|
|
525
2035
|
return ok(cast);
|
|
526
|
-
} catch (
|
|
527
|
-
const raw =
|
|
528
|
-
return err(occtError("THICKEN_FAILED", `Thicken operation failed: ${raw}`,
|
|
2036
|
+
} catch (e8) {
|
|
2037
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
2038
|
+
return err(occtError("THICKEN_FAILED", `Thicken operation failed: ${raw}`, e8));
|
|
529
2039
|
}
|
|
530
2040
|
}
|
|
531
2041
|
function fillet$1(shape2, edges, radius) {
|
|
@@ -567,8 +2077,8 @@ function fillet$1(shape2, edges, radius) {
|
|
|
567
2077
|
}
|
|
568
2078
|
try {
|
|
569
2079
|
const oc = getKernel().oc;
|
|
570
|
-
const
|
|
571
|
-
const builder =
|
|
2080
|
+
const r11 = gcWithScope();
|
|
2081
|
+
const builder = r11(
|
|
572
2082
|
new oc.BRepFilletAPI_MakeFillet(shape2.wrapped, oc.ChFi3d_FilletShape.ChFi3d_Rational)
|
|
573
2083
|
);
|
|
574
2084
|
for (const edge of selectedEdges) {
|
|
@@ -586,11 +2096,13 @@ function fillet$1(shape2, edges, radius) {
|
|
|
586
2096
|
return err(occtError("FILLET_RESULT_NOT_3D", "Fillet result is not a 3D shape"));
|
|
587
2097
|
}
|
|
588
2098
|
propagateOrigins(builder, [shape2], cast);
|
|
2099
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2100
|
+
propagateColors(builder, [shape2], cast);
|
|
589
2101
|
return ok(cast);
|
|
590
|
-
} catch (
|
|
591
|
-
const raw =
|
|
2102
|
+
} catch (e8) {
|
|
2103
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
592
2104
|
return err(
|
|
593
|
-
occtError("FILLET_FAILED", `Fillet operation failed: ${raw}`,
|
|
2105
|
+
occtError("FILLET_FAILED", `Fillet operation failed: ${raw}`, e8, {
|
|
594
2106
|
operation: "fillet",
|
|
595
2107
|
edgeCount: selectedEdges.length,
|
|
596
2108
|
radius
|
|
@@ -657,15 +2169,15 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
657
2169
|
return edgeFaceMap;
|
|
658
2170
|
};
|
|
659
2171
|
const oc = getKernel().oc;
|
|
660
|
-
const
|
|
661
|
-
const builder =
|
|
2172
|
+
const r11 = gcWithScope();
|
|
2173
|
+
const builder = r11(new oc.BRepFilletAPI_MakeChamfer(shape2.wrapped));
|
|
662
2174
|
let edgeFaceMap = null;
|
|
663
2175
|
for (const edge of selectedEdges) {
|
|
664
|
-
const
|
|
665
|
-
if (typeof
|
|
666
|
-
if (
|
|
2176
|
+
const d9 = typeof distance === "function" ? distance(edge) ?? 0 : distance;
|
|
2177
|
+
if (typeof d9 === "number") {
|
|
2178
|
+
if (d9 > 0) builder.Add_2(d9, edge.wrapped);
|
|
667
2179
|
} else {
|
|
668
|
-
const [d1, d22] =
|
|
2180
|
+
const [d1, d22] = d9;
|
|
669
2181
|
if (d1 > 0 && d22 > 0) {
|
|
670
2182
|
const face2 = getEdgeFaceMap().get(edge.wrapped.HashCode(2147483647));
|
|
671
2183
|
if (face2) {
|
|
@@ -680,11 +2192,13 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
680
2192
|
return err(occtError("CHAMFER_RESULT_NOT_3D", "Chamfer result is not a 3D shape"));
|
|
681
2193
|
}
|
|
682
2194
|
propagateOrigins(builder, [shape2], cast);
|
|
2195
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2196
|
+
propagateColors(builder, [shape2], cast);
|
|
683
2197
|
return ok(cast);
|
|
684
|
-
} catch (
|
|
685
|
-
const raw =
|
|
2198
|
+
} catch (e8) {
|
|
2199
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
686
2200
|
return err(
|
|
687
|
-
occtError("CHAMFER_FAILED", `Chamfer operation failed: ${raw}`,
|
|
2201
|
+
occtError("CHAMFER_FAILED", `Chamfer operation failed: ${raw}`, e8, {
|
|
688
2202
|
operation: "chamfer",
|
|
689
2203
|
edgeCount: selectedEdges.length,
|
|
690
2204
|
distance
|
|
@@ -703,13 +2217,13 @@ function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
|
|
|
703
2217
|
}
|
|
704
2218
|
try {
|
|
705
2219
|
const oc = getKernel().oc;
|
|
706
|
-
const
|
|
707
|
-
const facesToRemove =
|
|
2220
|
+
const r11 = gcWithScope();
|
|
2221
|
+
const facesToRemove = r11(new oc.TopTools_ListOfShape_1());
|
|
708
2222
|
for (const face2 of faces) {
|
|
709
2223
|
facesToRemove.Append_1(face2.wrapped);
|
|
710
2224
|
}
|
|
711
|
-
const progress =
|
|
712
|
-
const builder =
|
|
2225
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
2226
|
+
const builder = r11(new oc.BRepOffsetAPI_MakeThickSolid());
|
|
713
2227
|
builder.MakeThickSolidByJoin(
|
|
714
2228
|
shape2.wrapped,
|
|
715
2229
|
facesToRemove,
|
|
@@ -728,11 +2242,13 @@ function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
|
|
|
728
2242
|
return err(occtError("SHELL_RESULT_NOT_3D", "Shell result is not a 3D shape"));
|
|
729
2243
|
}
|
|
730
2244
|
propagateOrigins(builder, [shape2], cast);
|
|
2245
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2246
|
+
propagateColors(builder, [shape2], cast);
|
|
731
2247
|
return ok(cast);
|
|
732
|
-
} catch (
|
|
733
|
-
const raw =
|
|
2248
|
+
} catch (e8) {
|
|
2249
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
734
2250
|
return err(
|
|
735
|
-
occtError("SHELL_FAILED", `Shell operation failed: ${raw}`,
|
|
2251
|
+
occtError("SHELL_FAILED", `Shell operation failed: ${raw}`, e8, {
|
|
736
2252
|
operation: "shell",
|
|
737
2253
|
faceCount: faces.length,
|
|
738
2254
|
thickness
|
|
@@ -748,9 +2264,9 @@ function offset$1(shape2, distance, tolerance = 1e-6) {
|
|
|
748
2264
|
}
|
|
749
2265
|
try {
|
|
750
2266
|
const oc = getKernel().oc;
|
|
751
|
-
const
|
|
752
|
-
const progress =
|
|
753
|
-
const builder =
|
|
2267
|
+
const r11 = gcWithScope();
|
|
2268
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
2269
|
+
const builder = r11(new oc.BRepOffsetAPI_MakeOffsetShape());
|
|
754
2270
|
builder.PerformByJoin(
|
|
755
2271
|
shape2.wrapped,
|
|
756
2272
|
distance,
|
|
@@ -768,10 +2284,12 @@ function offset$1(shape2, distance, tolerance = 1e-6) {
|
|
|
768
2284
|
return err(occtError("OFFSET_RESULT_NOT_3D", "Offset result is not a 3D shape"));
|
|
769
2285
|
}
|
|
770
2286
|
propagateOrigins(builder, [shape2], cast);
|
|
2287
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2288
|
+
propagateColors(builder, [shape2], cast);
|
|
771
2289
|
return ok(cast);
|
|
772
|
-
} catch (
|
|
773
|
-
const raw =
|
|
774
|
-
return err(occtError("OFFSET_FAILED", `Offset operation failed: ${raw}`,
|
|
2290
|
+
} catch (e8) {
|
|
2291
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
2292
|
+
return err(occtError("OFFSET_FAILED", `Offset operation failed: ${raw}`, e8));
|
|
775
2293
|
}
|
|
776
2294
|
}
|
|
777
2295
|
function translate(shape2, v7) {
|
|
@@ -797,18 +2315,21 @@ function applyMatrix(shape2, matrix) {
|
|
|
797
2315
|
function transformCopy(shape2, composed) {
|
|
798
2316
|
return transformCopy$1(resolve(shape2), composed);
|
|
799
2317
|
}
|
|
800
|
-
function fuse(
|
|
801
|
-
return fuse$1(resolve(
|
|
2318
|
+
function fuse(a9, b11, options) {
|
|
2319
|
+
return fuse$1(resolve(a9), resolve(b11), options);
|
|
802
2320
|
}
|
|
803
2321
|
function cut(base, tool, options) {
|
|
804
2322
|
return cut$1(resolve(base), resolve(tool), options);
|
|
805
2323
|
}
|
|
806
|
-
function intersect(
|
|
807
|
-
return intersect$1(resolve(
|
|
2324
|
+
function intersect(a9, b11, options) {
|
|
2325
|
+
return intersect$1(resolve(a9), resolve(b11), options);
|
|
808
2326
|
}
|
|
809
2327
|
function section(shape2, plane, options) {
|
|
810
2328
|
return section$1(resolve(shape2), plane, options);
|
|
811
2329
|
}
|
|
2330
|
+
function sectionToFace(shape2, plane, options) {
|
|
2331
|
+
return sectionToFace$1(resolve(shape2), plane, options);
|
|
2332
|
+
}
|
|
812
2333
|
function split(shape2, tools) {
|
|
813
2334
|
return split$1(resolve(shape2), tools);
|
|
814
2335
|
}
|
|
@@ -853,24 +2374,24 @@ function normalizeChamferDistance(distance) {
|
|
|
853
2374
|
return { mode: "standard", distance };
|
|
854
2375
|
}
|
|
855
2376
|
function fillet(shape2, edgesOrRadius, maybeRadius) {
|
|
856
|
-
const
|
|
2377
|
+
const s6 = resolve(shape2);
|
|
857
2378
|
let edges;
|
|
858
2379
|
let radius;
|
|
859
2380
|
if (maybeRadius !== void 0) {
|
|
860
|
-
edges = resolveEdges(edgesOrRadius,
|
|
2381
|
+
edges = resolveEdges(edgesOrRadius, s6);
|
|
861
2382
|
radius = maybeRadius;
|
|
862
2383
|
} else {
|
|
863
2384
|
edges = void 0;
|
|
864
2385
|
radius = edgesOrRadius;
|
|
865
2386
|
}
|
|
866
|
-
return fillet$1(
|
|
2387
|
+
return fillet$1(s6, edges, normalizeFilletRadius(radius));
|
|
867
2388
|
}
|
|
868
2389
|
function chamfer(shape2, edgesOrDistance, maybeDistance) {
|
|
869
|
-
const
|
|
2390
|
+
const s6 = resolve(shape2);
|
|
870
2391
|
let edges;
|
|
871
2392
|
let distance;
|
|
872
2393
|
if (maybeDistance !== void 0) {
|
|
873
|
-
edges = resolveEdges(edgesOrDistance,
|
|
2394
|
+
edges = resolveEdges(edgesOrDistance, s6);
|
|
874
2395
|
distance = maybeDistance;
|
|
875
2396
|
} else {
|
|
876
2397
|
edges = void 0;
|
|
@@ -878,20 +2399,20 @@ function chamfer(shape2, edgesOrDistance, maybeDistance) {
|
|
|
878
2399
|
}
|
|
879
2400
|
const normalized = normalizeChamferDistance(distance);
|
|
880
2401
|
if (normalized.mode === "distAngle") {
|
|
881
|
-
const selectedEdges = edges ?? getEdges(
|
|
2402
|
+
const selectedEdges = edges ?? getEdges(s6);
|
|
882
2403
|
return chamferDistAngle(
|
|
883
|
-
|
|
2404
|
+
s6,
|
|
884
2405
|
[...selectedEdges],
|
|
885
2406
|
normalized.distance,
|
|
886
2407
|
normalized.angle
|
|
887
2408
|
);
|
|
888
2409
|
}
|
|
889
|
-
return chamfer$1(
|
|
2410
|
+
return chamfer$1(s6, edges, normalized.distance);
|
|
890
2411
|
}
|
|
891
2412
|
function shell(shape2, faces, thickness, options) {
|
|
892
|
-
const
|
|
893
|
-
const resolvedFaces = resolveFaces(faces,
|
|
894
|
-
return shell$1(
|
|
2413
|
+
const s6 = resolve(shape2);
|
|
2414
|
+
const resolvedFaces = resolveFaces(faces, s6);
|
|
2415
|
+
return shell$1(s6, resolvedFaces, thickness, options?.tolerance);
|
|
895
2416
|
}
|
|
896
2417
|
function offset(shape2, distance, options) {
|
|
897
2418
|
return offset$1(resolve(shape2), distance, options?.tolerance);
|
|
@@ -931,22 +2452,22 @@ function loft$1(wires, { ruled = true, startPoint, endPoint } = {}, returnShell
|
|
|
931
2452
|
return err(validationError("LOFT_EMPTY", "Loft requires at least one wire or start/end point"));
|
|
932
2453
|
}
|
|
933
2454
|
const oc = getKernel().oc;
|
|
934
|
-
const
|
|
935
|
-
const builder =
|
|
2455
|
+
const r11 = gcWithScope();
|
|
2456
|
+
const builder = r11(new oc.BRepOffsetAPI_ThruSections(!returnShell, ruled, 1e-6));
|
|
936
2457
|
if (startPoint) {
|
|
937
|
-
const pnt =
|
|
938
|
-
const vMaker =
|
|
2458
|
+
const pnt = r11(toOcPnt(toVec3(startPoint)));
|
|
2459
|
+
const vMaker = r11(new oc.BRepBuilderAPI_MakeVertex(pnt));
|
|
939
2460
|
builder.AddVertex(vMaker.Vertex());
|
|
940
2461
|
}
|
|
941
|
-
for (const
|
|
942
|
-
builder.AddWire(
|
|
2462
|
+
for (const w7 of wires) {
|
|
2463
|
+
builder.AddWire(w7.wrapped);
|
|
943
2464
|
}
|
|
944
2465
|
if (endPoint) {
|
|
945
|
-
const pnt =
|
|
946
|
-
const vMaker =
|
|
2466
|
+
const pnt = r11(toOcPnt(toVec3(endPoint)));
|
|
2467
|
+
const vMaker = r11(new oc.BRepBuilderAPI_MakeVertex(pnt));
|
|
947
2468
|
builder.AddVertex(vMaker.Vertex());
|
|
948
2469
|
}
|
|
949
|
-
const progress =
|
|
2470
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
950
2471
|
builder.Build(progress);
|
|
951
2472
|
if (!builder.IsDone()) {
|
|
952
2473
|
return err(occtError("LOFT_FAILED", "Loft operation failed"));
|
|
@@ -958,9 +2479,9 @@ function loft$1(wires, { ruled = true, startPoint, endPoint } = {}, returnShell
|
|
|
958
2479
|
return ok(result);
|
|
959
2480
|
}
|
|
960
2481
|
function extrude(face2, height) {
|
|
961
|
-
const
|
|
2482
|
+
const f12 = resolve(face2);
|
|
962
2483
|
const vec = typeof height === "number" ? [0, 0, height] : height;
|
|
963
|
-
return extrude$1(
|
|
2484
|
+
return extrude$1(f12, vec);
|
|
964
2485
|
}
|
|
965
2486
|
function revolve(face2, options) {
|
|
966
2487
|
const pivotPoint = options?.at ?? [0, 0, 0];
|
|
@@ -972,7 +2493,7 @@ function revolve(face2, options) {
|
|
|
972
2493
|
);
|
|
973
2494
|
}
|
|
974
2495
|
function loft(wires, options) {
|
|
975
|
-
const resolvedWires = wires.map((
|
|
2496
|
+
const resolvedWires = wires.map((w7) => resolve(w7));
|
|
976
2497
|
return loft$1(resolvedWires, options);
|
|
977
2498
|
}
|
|
978
2499
|
function resolveTargetFace(shape2, faceSpec) {
|
|
@@ -983,12 +2504,12 @@ function resolveTargetFace(shape2, faceSpec) {
|
|
|
983
2504
|
}
|
|
984
2505
|
let best = faces[0];
|
|
985
2506
|
let bestZ = faceCenter(best)[2];
|
|
986
|
-
for (let
|
|
987
|
-
const
|
|
988
|
-
const
|
|
989
|
-
if (
|
|
990
|
-
best =
|
|
991
|
-
bestZ =
|
|
2507
|
+
for (let i8 = 1; i8 < faces.length; i8++) {
|
|
2508
|
+
const f12 = faces[i8];
|
|
2509
|
+
const z6 = faceCenter(f12)[2];
|
|
2510
|
+
if (z6 > bestZ) {
|
|
2511
|
+
best = f12;
|
|
2512
|
+
bestZ = z6;
|
|
992
2513
|
}
|
|
993
2514
|
}
|
|
994
2515
|
return best;
|
|
@@ -1010,7 +2531,7 @@ function toWire(profile) {
|
|
|
1010
2531
|
return profile;
|
|
1011
2532
|
}
|
|
1012
2533
|
function drill(shape2, options) {
|
|
1013
|
-
const
|
|
2534
|
+
const s6 = resolve(shape2);
|
|
1014
2535
|
const { at, radius, axis: rawAxis } = options;
|
|
1015
2536
|
const axis = rawAxis ?? [0, 0, 1];
|
|
1016
2537
|
if (radius <= 0) {
|
|
@@ -1023,7 +2544,7 @@ function drill(shape2, options) {
|
|
|
1023
2544
|
const pos = at.length === 2 ? [at[0], at[1], 0] : [at[0], at[1], at[2]];
|
|
1024
2545
|
let depth = options.depth;
|
|
1025
2546
|
if (depth === void 0) {
|
|
1026
|
-
const b11 = getBounds(
|
|
2547
|
+
const b11 = getBounds(s6);
|
|
1027
2548
|
const dx = b11.xMax - b11.xMin;
|
|
1028
2549
|
const dy = b11.yMax - b11.yMin;
|
|
1029
2550
|
const dz = b11.zMax - b11.zMin;
|
|
@@ -1032,49 +2553,49 @@ function drill(shape2, options) {
|
|
|
1032
2553
|
const cyl = makeCylinder(radius, depth, pos, dir);
|
|
1033
2554
|
const startOffset = options.depth === void 0 ? vecScale(dir, -depth / 2) : [0, 0, 0];
|
|
1034
2555
|
const tool = startOffset[0] !== 0 || startOffset[1] !== 0 || startOffset[2] !== 0 ? translate$1(cyl, startOffset) : cyl;
|
|
1035
|
-
return cut$1(
|
|
2556
|
+
return cut$1(s6, tool);
|
|
1036
2557
|
}
|
|
1037
2558
|
function pocket(shape2, options) {
|
|
1038
|
-
const
|
|
2559
|
+
const s6 = resolve(shape2);
|
|
1039
2560
|
const { profile, depth } = options;
|
|
1040
2561
|
if (depth <= 0) {
|
|
1041
2562
|
return err(validationError("POCKET_INVALID_DEPTH", "Pocket depth must be positive"));
|
|
1042
2563
|
}
|
|
1043
|
-
const targetFace = resolveTargetFace(
|
|
2564
|
+
const targetFace = resolveTargetFace(s6, options.face);
|
|
1044
2565
|
const normal = normalAt(targetFace);
|
|
1045
|
-
const
|
|
1046
|
-
const faceResult = makeFace(
|
|
2566
|
+
const w7 = toWire(profile);
|
|
2567
|
+
const faceResult = makeFace(w7);
|
|
1047
2568
|
if (isErr(faceResult)) return faceResult;
|
|
1048
2569
|
const extDir = vecScale(vecNormalize(normal), -depth);
|
|
1049
2570
|
const toolResult = extrude$1(faceResult.value, extDir);
|
|
1050
2571
|
if (isErr(toolResult)) return toolResult;
|
|
1051
|
-
return cut$1(
|
|
2572
|
+
return cut$1(s6, toolResult.value);
|
|
1052
2573
|
}
|
|
1053
2574
|
function boss(shape2, options) {
|
|
1054
|
-
const
|
|
2575
|
+
const s6 = resolve(shape2);
|
|
1055
2576
|
const { profile, height } = options;
|
|
1056
2577
|
if (height <= 0) {
|
|
1057
2578
|
return err(validationError("BOSS_INVALID_HEIGHT", "Boss height must be positive"));
|
|
1058
2579
|
}
|
|
1059
|
-
const targetFace = resolveTargetFace(
|
|
2580
|
+
const targetFace = resolveTargetFace(s6, options.face);
|
|
1060
2581
|
const normal = normalAt(targetFace);
|
|
1061
|
-
const
|
|
1062
|
-
const faceResult = makeFace(
|
|
2582
|
+
const w7 = toWire(profile);
|
|
2583
|
+
const faceResult = makeFace(w7);
|
|
1063
2584
|
if (isErr(faceResult)) return faceResult;
|
|
1064
2585
|
const extDir = vecScale(vecNormalize(normal), height);
|
|
1065
2586
|
const toolResult = extrude$1(faceResult.value, extDir);
|
|
1066
2587
|
if (isErr(toolResult)) return toolResult;
|
|
1067
|
-
return fuse$1(
|
|
2588
|
+
return fuse$1(s6, toolResult.value);
|
|
1068
2589
|
}
|
|
1069
2590
|
function mirrorJoin(shape2, options) {
|
|
1070
|
-
const
|
|
2591
|
+
const s6 = resolve(shape2);
|
|
1071
2592
|
const normal = options?.normal ?? [1, 0, 0];
|
|
1072
2593
|
const planeOrigin = options?.at;
|
|
1073
|
-
const mirrored = mirror$1(
|
|
1074
|
-
return fuse$1(
|
|
2594
|
+
const mirrored = mirror$1(s6, normal, planeOrigin);
|
|
2595
|
+
return fuse$1(s6, mirrored);
|
|
1075
2596
|
}
|
|
1076
2597
|
function rectangularPattern(shape2, options) {
|
|
1077
|
-
const
|
|
2598
|
+
const s6 = resolve(shape2);
|
|
1078
2599
|
const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options;
|
|
1079
2600
|
if (xCount < 1 || yCount < 1) {
|
|
1080
2601
|
return err(validationError("PATTERN_INVALID_COUNT", "Pattern counts must be at least 1"));
|
|
@@ -1085,10 +2606,10 @@ function rectangularPattern(shape2, options) {
|
|
|
1085
2606
|
if (vecIsZero(yDir)) {
|
|
1086
2607
|
return err(validationError("PATTERN_ZERO_DIRECTION", "Y direction cannot be zero"));
|
|
1087
2608
|
}
|
|
1088
|
-
if (xCount === 1 && yCount === 1) return ok(
|
|
2609
|
+
if (xCount === 1 && yCount === 1) return ok(s6);
|
|
1089
2610
|
const xNorm = vecNormalize(xDir);
|
|
1090
2611
|
const yNorm = vecNormalize(yDir);
|
|
1091
|
-
const copies = [
|
|
2612
|
+
const copies = [s6];
|
|
1092
2613
|
for (let xi = 0; xi < xCount; xi++) {
|
|
1093
2614
|
for (let yi = 0; yi < yCount; yi++) {
|
|
1094
2615
|
if (xi === 0 && yi === 0) continue;
|
|
@@ -1097,7 +2618,7 @@ function rectangularPattern(shape2, options) {
|
|
|
1097
2618
|
xNorm[1] * xSpacing * xi + yNorm[1] * ySpacing * yi,
|
|
1098
2619
|
xNorm[2] * xSpacing * xi + yNorm[2] * ySpacing * yi
|
|
1099
2620
|
];
|
|
1100
|
-
copies.push(translate$1(
|
|
2621
|
+
copies.push(translate$1(s6, offset2));
|
|
1101
2622
|
}
|
|
1102
2623
|
}
|
|
1103
2624
|
return fuseAll(copies);
|
|
@@ -1138,12 +2659,12 @@ function createWrappedBase(val) {
|
|
|
1138
2659
|
mirror: (opts) => wrapAny(mirror(val, opts)),
|
|
1139
2660
|
scale: (factor, opts) => wrapAny(scale(val, factor, opts)),
|
|
1140
2661
|
applyMatrix: (matrix) => wrapAny(applyMatrix(val, matrix)),
|
|
1141
|
-
moveX: (
|
|
1142
|
-
moveY: (
|
|
1143
|
-
moveZ: (
|
|
1144
|
-
rotateX: (
|
|
1145
|
-
rotateY: (
|
|
1146
|
-
rotateZ: (
|
|
2662
|
+
moveX: (d9) => wrapAny(translate(val, [d9, 0, 0])),
|
|
2663
|
+
moveY: (d9) => wrapAny(translate(val, [0, d9, 0])),
|
|
2664
|
+
moveZ: (d9) => wrapAny(translate(val, [0, 0, d9])),
|
|
2665
|
+
rotateX: (a9) => wrapAny(rotate(val, a9, { axis: [1, 0, 0] })),
|
|
2666
|
+
rotateY: (a9) => wrapAny(rotate(val, a9, { axis: [0, 1, 0] })),
|
|
2667
|
+
rotateZ: (a9) => wrapAny(rotate(val, a9, { axis: [0, 0, 1] })),
|
|
1147
2668
|
bounds: () => getBounds(val),
|
|
1148
2669
|
describe: () => describe(val),
|
|
1149
2670
|
clone: () => wrapAny(clone(val)),
|
|
@@ -1222,13 +2743,13 @@ function createWrappedCurve(val) {
|
|
|
1222
2743
|
length: () => curveLength(val),
|
|
1223
2744
|
startPoint: () => curveStartPoint(val),
|
|
1224
2745
|
endPoint: () => curveEndPoint(val),
|
|
1225
|
-
pointAt: (
|
|
1226
|
-
tangentAt: (
|
|
2746
|
+
pointAt: (t11) => curvePointAt(val, t11),
|
|
2747
|
+
tangentAt: (t11) => curveTangentAt(val, t11),
|
|
1227
2748
|
isClosed: () => curveIsClosed(val),
|
|
1228
2749
|
sweep(spine, opts) {
|
|
1229
2750
|
if (!isWire(val)) throw new Error("sweep requires a Wire");
|
|
1230
|
-
const
|
|
1231
|
-
const result = unwrapOrThrow(sweep(
|
|
2751
|
+
const w7 = val;
|
|
2752
|
+
const result = unwrapOrThrow(sweep(w7, resolve(spine), opts));
|
|
1232
2753
|
const shape3D = Array.isArray(result) ? result[0] : result;
|
|
1233
2754
|
return wrap3D(shape3D);
|
|
1234
2755
|
}
|
|
@@ -1257,15 +2778,15 @@ function wrapAny(val) {
|
|
|
1257
2778
|
function wrap3D(val) {
|
|
1258
2779
|
return createWrapped3D(val);
|
|
1259
2780
|
}
|
|
1260
|
-
function shape(
|
|
1261
|
-
if (
|
|
1262
|
-
return createWrappedFace(
|
|
2781
|
+
function shape(s6) {
|
|
2782
|
+
if (s6 && typeof s6 === "object" && "face" in s6 && typeof s6.face === "function" && "_defaultOrigin" in s6) {
|
|
2783
|
+
return createWrappedFace(s6.face());
|
|
1263
2784
|
}
|
|
1264
|
-
if (
|
|
1265
|
-
if (isFace(
|
|
1266
|
-
if (isShape3D(
|
|
1267
|
-
if (isEdge(
|
|
1268
|
-
return createWrappedBase(
|
|
2785
|
+
if (s6 && typeof s6 === "object" && "wrapped" in s6) {
|
|
2786
|
+
if (isFace(s6)) return createWrappedFace(s6);
|
|
2787
|
+
if (isShape3D(s6)) return createWrapped3D(s6);
|
|
2788
|
+
if (isEdge(s6) || isWire(s6)) return createWrappedCurve(s6);
|
|
2789
|
+
return createWrappedBase(s6);
|
|
1269
2790
|
}
|
|
1270
2791
|
throw new Error("shape() requires a Sketch or branded shape type");
|
|
1271
2792
|
}
|
|
@@ -1273,8 +2794,8 @@ export {
|
|
|
1273
2794
|
B3 as BaseSketcher2d,
|
|
1274
2795
|
B as Blueprint,
|
|
1275
2796
|
a5 as BlueprintSketcher,
|
|
1276
|
-
|
|
1277
|
-
|
|
2797
|
+
e2 as Blueprints,
|
|
2798
|
+
d2 as BoundingBox2d,
|
|
1278
2799
|
BrepBugError,
|
|
1279
2800
|
BrepErrorCode,
|
|
1280
2801
|
BrepWrapperError,
|
|
@@ -1291,19 +2812,20 @@ export {
|
|
|
1291
2812
|
R as RAD2DEG,
|
|
1292
2813
|
S as Sketch,
|
|
1293
2814
|
S2 as Sketcher,
|
|
1294
|
-
|
|
2815
|
+
b8 as Sketches,
|
|
1295
2816
|
a4 as addChild,
|
|
1296
2817
|
addHoles,
|
|
1297
|
-
|
|
2818
|
+
addMate,
|
|
2819
|
+
b7 as addStep,
|
|
1298
2820
|
a8 as adjacentFaces,
|
|
1299
2821
|
a as andThen,
|
|
1300
|
-
|
|
2822
|
+
j6 as applyGlue,
|
|
1301
2823
|
applyMatrix,
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
2824
|
+
j3 as approximateCurve,
|
|
2825
|
+
l9 as asTopo,
|
|
2826
|
+
b9 as autoHeal,
|
|
2827
|
+
r4 as axis2d,
|
|
2828
|
+
b6 as basicFaceExtrusion,
|
|
1307
2829
|
bezier,
|
|
1308
2830
|
blueprintToDXF,
|
|
1309
2831
|
boss,
|
|
@@ -1312,7 +2834,7 @@ export {
|
|
|
1312
2834
|
bug,
|
|
1313
2835
|
X as cameraFromPlane,
|
|
1314
2836
|
Y as cameraLookAt,
|
|
1315
|
-
|
|
2837
|
+
c4 as cast,
|
|
1316
2838
|
castShape,
|
|
1317
2839
|
chamfer,
|
|
1318
2840
|
chamferDistAngle as chamferDistAngleShape,
|
|
@@ -1320,43 +2842,46 @@ export {
|
|
|
1320
2842
|
checkInterference,
|
|
1321
2843
|
circle,
|
|
1322
2844
|
circularPattern,
|
|
1323
|
-
|
|
1324
|
-
|
|
2845
|
+
m7 as classifyPointOnFace,
|
|
2846
|
+
c5 as clearMeshCache,
|
|
1325
2847
|
clone,
|
|
1326
|
-
|
|
1327
|
-
|
|
2848
|
+
c as collect,
|
|
2849
|
+
d3 as collectShapes,
|
|
2850
|
+
k8 as colorFaces,
|
|
2851
|
+
l7 as colorShape,
|
|
1328
2852
|
f5 as complexExtrude,
|
|
1329
|
-
|
|
2853
|
+
w5 as composeTransforms,
|
|
1330
2854
|
compound,
|
|
1331
|
-
|
|
2855
|
+
c2 as compoundSketchExtrude,
|
|
1332
2856
|
d4 as compoundSketchFace,
|
|
1333
|
-
|
|
2857
|
+
e3 as compoundSketchLoft,
|
|
1334
2858
|
f7 as compoundSketchRevolve,
|
|
1335
|
-
|
|
2859
|
+
b2 as computationError,
|
|
2860
|
+
computeStraightSkeleton,
|
|
1336
2861
|
cone,
|
|
1337
|
-
|
|
2862
|
+
c6 as cornerFinder,
|
|
1338
2863
|
g6 as countNodes,
|
|
1339
|
-
|
|
1340
|
-
|
|
2864
|
+
h4 as createAssembly,
|
|
2865
|
+
i4 as createAssemblyNode,
|
|
1341
2866
|
createBlueprint,
|
|
1342
2867
|
Z as createCamera,
|
|
1343
|
-
|
|
2868
|
+
s2 as createCompound,
|
|
1344
2869
|
d8 as createDistanceQuery,
|
|
1345
|
-
|
|
1346
|
-
|
|
2870
|
+
p as createEdge,
|
|
2871
|
+
q as createFace,
|
|
1347
2872
|
a2 as createHandle,
|
|
1348
|
-
|
|
2873
|
+
j4 as createHistory,
|
|
1349
2874
|
b10 as createMeshCache,
|
|
1350
|
-
|
|
1351
|
-
|
|
2875
|
+
c3 as createNamedPlane,
|
|
2876
|
+
b3 as createOcHandle,
|
|
1352
2877
|
createOperationRegistry,
|
|
1353
2878
|
a7 as createPlane,
|
|
1354
2879
|
k5 as createRegistry,
|
|
1355
|
-
|
|
2880
|
+
y as createShell,
|
|
1356
2881
|
createSolid,
|
|
1357
2882
|
createTaskQueue,
|
|
1358
|
-
|
|
1359
|
-
|
|
2883
|
+
t3 as createVertex,
|
|
2884
|
+
createWire,
|
|
1360
2885
|
createWorkerClient,
|
|
1361
2886
|
createWorkerHandler,
|
|
1362
2887
|
curve2dBoundingBox,
|
|
@@ -1369,41 +2894,41 @@ export {
|
|
|
1369
2894
|
curve2dTangentAt,
|
|
1370
2895
|
curveEndPoint,
|
|
1371
2896
|
curveIsClosed,
|
|
1372
|
-
|
|
2897
|
+
k4 as curveIsPeriodic,
|
|
1373
2898
|
curveLength,
|
|
1374
|
-
|
|
2899
|
+
l4 as curvePeriod,
|
|
1375
2900
|
curvePointAt,
|
|
1376
2901
|
curveStartPoint,
|
|
1377
2902
|
curveTangentAt,
|
|
1378
2903
|
cut,
|
|
1379
|
-
|
|
2904
|
+
f6 as cut2D,
|
|
1380
2905
|
cutAll,
|
|
1381
|
-
|
|
2906
|
+
l5 as cutBlueprints,
|
|
1382
2907
|
cylinder,
|
|
1383
2908
|
dequeueTask,
|
|
1384
2909
|
describe,
|
|
1385
2910
|
g9 as deserializeDrawing,
|
|
1386
2911
|
fromBREP$1 as deserializeShape,
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
2912
|
+
d6 as downcast,
|
|
2913
|
+
h5 as draw,
|
|
2914
|
+
i5 as drawCircle,
|
|
2915
|
+
j5 as drawEllipse,
|
|
2916
|
+
k7 as drawFaceOutline,
|
|
2917
|
+
l6 as drawParametricFunction,
|
|
1393
2918
|
m5 as drawPointsInterpolation,
|
|
1394
2919
|
n5 as drawPolysides,
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
2920
|
+
o5 as drawProjection,
|
|
2921
|
+
p4 as drawRectangle,
|
|
2922
|
+
q4 as drawRoundedRectangle,
|
|
2923
|
+
r7 as drawSingleCircle,
|
|
2924
|
+
s3 as drawSingleEllipse,
|
|
2925
|
+
t6 as drawText,
|
|
2926
|
+
u2 as drawingChamfer,
|
|
2927
|
+
v4 as drawingCut,
|
|
2928
|
+
w4 as drawingFillet,
|
|
2929
|
+
x2 as drawingFuse,
|
|
2930
|
+
y3 as drawingIntersect,
|
|
2931
|
+
z4 as drawingToSketchOnPlane,
|
|
1407
2932
|
drill,
|
|
1408
2933
|
edgeFinder,
|
|
1409
2934
|
e5 as edgesOfFace,
|
|
@@ -1416,79 +2941,90 @@ export {
|
|
|
1416
2941
|
exportDXF,
|
|
1417
2942
|
exportGlb,
|
|
1418
2943
|
exportGltf,
|
|
1419
|
-
|
|
2944
|
+
e6 as exportIGES,
|
|
1420
2945
|
exportOBJ,
|
|
1421
2946
|
d7 as exportSTEP,
|
|
1422
|
-
|
|
2947
|
+
f10 as exportSTL,
|
|
1423
2948
|
exportThreeMF,
|
|
1424
2949
|
extrude,
|
|
1425
2950
|
face,
|
|
1426
2951
|
faceCenter,
|
|
1427
2952
|
faceFinder,
|
|
1428
|
-
|
|
1429
|
-
|
|
2953
|
+
f9 as faceGeomType,
|
|
2954
|
+
q6 as faceOrientation,
|
|
1430
2955
|
f8 as facesOfEdge,
|
|
2956
|
+
p7 as fill,
|
|
1431
2957
|
filledFace,
|
|
1432
2958
|
fillet,
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
2959
|
+
f4 as findCurveType,
|
|
2960
|
+
m6 as findFacesByTag,
|
|
2961
|
+
n3 as findNode,
|
|
2962
|
+
o3 as findStep,
|
|
1436
2963
|
f2 as flatMap,
|
|
1437
|
-
|
|
1438
|
-
|
|
2964
|
+
r10 as flipFaceOrientation,
|
|
2965
|
+
m3 as flipOrientation,
|
|
2966
|
+
_ as fontMetrics,
|
|
1439
2967
|
fromBREP,
|
|
1440
2968
|
f as fromOcDir,
|
|
1441
2969
|
h as fromOcPnt,
|
|
1442
2970
|
i as fromOcVec,
|
|
1443
2971
|
fuse,
|
|
1444
|
-
|
|
2972
|
+
g7 as fuse2D,
|
|
1445
2973
|
fuseAll,
|
|
1446
|
-
|
|
1447
|
-
|
|
2974
|
+
n4 as fuseBlueprints,
|
|
2975
|
+
z2 as gcWithObject,
|
|
1448
2976
|
gcWithScope,
|
|
1449
|
-
|
|
2977
|
+
g5 as genericSweep,
|
|
1450
2978
|
getBounds,
|
|
1451
2979
|
getBounds2D,
|
|
1452
|
-
|
|
2980
|
+
b5 as getCurveType,
|
|
1453
2981
|
getEdges,
|
|
2982
|
+
n6 as getFaceColor,
|
|
1454
2983
|
g10 as getFaceOrigins,
|
|
2984
|
+
o6 as getFaceTags,
|
|
1455
2985
|
getFaces,
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
2986
|
+
$ as getFont,
|
|
2987
|
+
e4 as getHashCode,
|
|
2988
|
+
p2 as getHistoryShape,
|
|
1459
2989
|
getKernel,
|
|
1460
|
-
|
|
2990
|
+
g4 as getOrientation,
|
|
1461
2991
|
getOrientation2D,
|
|
2992
|
+
q5 as getShapeColor,
|
|
1462
2993
|
g2 as getShapeKind,
|
|
1463
2994
|
g8 as getSingleFace,
|
|
1464
2995
|
getSurfaceType,
|
|
2996
|
+
r9 as getTagMetadata,
|
|
1465
2997
|
getVertices,
|
|
1466
2998
|
getWires,
|
|
2999
|
+
guidedSweep,
|
|
1467
3000
|
heal,
|
|
1468
3001
|
d5 as healFace,
|
|
1469
3002
|
g11 as healSolid,
|
|
1470
|
-
|
|
3003
|
+
j7 as healWire,
|
|
1471
3004
|
helix,
|
|
1472
3005
|
hull,
|
|
3006
|
+
importDXF,
|
|
1473
3007
|
importIGES,
|
|
3008
|
+
importOBJ,
|
|
1474
3009
|
importSTEP,
|
|
1475
3010
|
importSTL,
|
|
1476
3011
|
importSVG,
|
|
1477
3012
|
importSVGPathD,
|
|
3013
|
+
importThreeMF,
|
|
1478
3014
|
j as initFromOC,
|
|
1479
3015
|
innerWires,
|
|
1480
|
-
|
|
3016
|
+
n2 as interpolateCurve,
|
|
1481
3017
|
intersect,
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
3018
|
+
k6 as intersect2D,
|
|
3019
|
+
q3 as intersectBlueprints,
|
|
3020
|
+
ioError,
|
|
1485
3021
|
isChamferRadius,
|
|
1486
|
-
|
|
1487
|
-
|
|
3022
|
+
s5 as isCompSolid,
|
|
3023
|
+
i2 as isCompound,
|
|
1488
3024
|
isDisposeRequest,
|
|
1489
3025
|
isEdge,
|
|
1490
3026
|
isEmpty,
|
|
1491
|
-
|
|
3027
|
+
x3 as isEqualShape,
|
|
1492
3028
|
isErr,
|
|
1493
3029
|
isErrorResponse,
|
|
1494
3030
|
isFace,
|
|
@@ -1498,19 +3034,19 @@ export {
|
|
|
1498
3034
|
isNumber,
|
|
1499
3035
|
g as isOk,
|
|
1500
3036
|
isOperationRequest,
|
|
1501
|
-
|
|
3037
|
+
a0 as isProjectionPlane,
|
|
1502
3038
|
isQueueEmpty,
|
|
1503
|
-
|
|
3039
|
+
i6 as isSameShape,
|
|
1504
3040
|
f3 as isShape1D,
|
|
1505
3041
|
isShape3D,
|
|
1506
|
-
|
|
3042
|
+
isShell,
|
|
1507
3043
|
isSolid,
|
|
1508
3044
|
isSuccessResponse,
|
|
1509
3045
|
isValid,
|
|
1510
3046
|
l2 as isVertex,
|
|
1511
3047
|
isWire,
|
|
1512
|
-
|
|
1513
|
-
|
|
3048
|
+
y4 as iterEdges,
|
|
3049
|
+
z5 as iterFaces,
|
|
1514
3050
|
iterTopo,
|
|
1515
3051
|
A3 as iterVertices,
|
|
1516
3052
|
B5 as iterWires,
|
|
@@ -1518,21 +3054,21 @@ export {
|
|
|
1518
3054
|
kernelCallRaw,
|
|
1519
3055
|
line,
|
|
1520
3056
|
linearPattern,
|
|
1521
|
-
|
|
1522
|
-
|
|
3057
|
+
a1 as loadFont,
|
|
3058
|
+
r3 as localGC,
|
|
1523
3059
|
loft,
|
|
1524
3060
|
A2 as makeBaseBox,
|
|
1525
|
-
|
|
1526
|
-
|
|
3061
|
+
t4 as makePlane,
|
|
3062
|
+
a22 as makeProjectedEdges,
|
|
1527
3063
|
m as map,
|
|
1528
3064
|
h2 as mapErr,
|
|
1529
3065
|
j2 as match,
|
|
1530
3066
|
measureArea,
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
3067
|
+
e7 as measureCurvatureAt,
|
|
3068
|
+
f11 as measureCurvatureAtMid,
|
|
3069
|
+
g12 as measureDistance,
|
|
3070
|
+
h7 as measureLength,
|
|
3071
|
+
i7 as measureLinearProps,
|
|
1536
3072
|
measureSurfaceProps,
|
|
1537
3073
|
measureVolume,
|
|
1538
3074
|
measureVolumeProps,
|
|
@@ -1545,53 +3081,59 @@ export {
|
|
|
1545
3081
|
mirrorJoin,
|
|
1546
3082
|
q2 as modifyStep,
|
|
1547
3083
|
k2 as moduleInitError,
|
|
3084
|
+
multiSectionSweep,
|
|
1548
3085
|
normalAt,
|
|
1549
3086
|
occtError,
|
|
1550
3087
|
offset,
|
|
1551
3088
|
offsetFace,
|
|
1552
|
-
|
|
3089
|
+
o2 as offsetWire2D,
|
|
1553
3090
|
ok,
|
|
1554
|
-
|
|
3091
|
+
o4 as organiseBlueprints,
|
|
1555
3092
|
outerWire,
|
|
1556
3093
|
pendingCount,
|
|
1557
3094
|
z as pipeline,
|
|
1558
|
-
|
|
3095
|
+
p5 as pivotPlane,
|
|
1559
3096
|
pocket,
|
|
1560
|
-
|
|
3097
|
+
p6 as pointOnSurface,
|
|
1561
3098
|
polygon,
|
|
3099
|
+
polyhedron,
|
|
1562
3100
|
E2 as polysideInnerRadius,
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
3101
|
+
p3 as polysidesBlueprint,
|
|
3102
|
+
a32 as projectEdges,
|
|
3103
|
+
t10 as projectPointOnFace,
|
|
1566
3104
|
queryError,
|
|
1567
3105
|
rectangularPattern,
|
|
1568
3106
|
registerHandler,
|
|
1569
|
-
|
|
1570
|
-
|
|
3107
|
+
t5 as registerOperation,
|
|
3108
|
+
u as registerShape,
|
|
1571
3109
|
rejectAll,
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
3110
|
+
v3 as removeChild,
|
|
3111
|
+
x as replayFrom,
|
|
3112
|
+
y2 as replayHistory,
|
|
3113
|
+
C5 as resize,
|
|
1575
3114
|
resolve,
|
|
1576
3115
|
resolve3D,
|
|
1577
3116
|
r as resolveDirection,
|
|
1578
|
-
|
|
3117
|
+
r8 as resolvePlane,
|
|
1579
3118
|
reverseCurve,
|
|
1580
|
-
|
|
3119
|
+
r5 as revolution,
|
|
1581
3120
|
revolve,
|
|
3121
|
+
roof,
|
|
1582
3122
|
rotate,
|
|
1583
3123
|
rotate2D,
|
|
1584
3124
|
F2 as rotateDrawing,
|
|
1585
|
-
|
|
3125
|
+
r6 as roundedRectangleBlueprint,
|
|
1586
3126
|
scale,
|
|
1587
3127
|
scale2D,
|
|
1588
3128
|
G as scaleDrawing,
|
|
1589
3129
|
section,
|
|
1590
|
-
|
|
3130
|
+
sectionToFace,
|
|
3131
|
+
D4 as setShapeOrigin,
|
|
3132
|
+
t8 as setTagMetadata,
|
|
1591
3133
|
sewShells,
|
|
1592
3134
|
shape,
|
|
1593
|
-
|
|
1594
|
-
|
|
3135
|
+
v6 as shapeType,
|
|
3136
|
+
s4 as sharedEdges,
|
|
1595
3137
|
shell,
|
|
1596
3138
|
simplify,
|
|
1597
3139
|
sketch2DOnFace,
|
|
@@ -1609,28 +3151,33 @@ export {
|
|
|
1609
3151
|
R2 as sketchRevolve,
|
|
1610
3152
|
T as sketchRoundedRectangle,
|
|
1611
3153
|
U as sketchSweep,
|
|
1612
|
-
|
|
3154
|
+
a42 as sketchText,
|
|
1613
3155
|
V as sketchWires,
|
|
1614
3156
|
s as sketcherStateError,
|
|
1615
3157
|
slice,
|
|
1616
3158
|
solid,
|
|
3159
|
+
solveAssembly,
|
|
1617
3160
|
sphere,
|
|
1618
3161
|
split,
|
|
1619
|
-
|
|
1620
|
-
|
|
3162
|
+
z3 as stepCount,
|
|
3163
|
+
A as stepsFrom,
|
|
1621
3164
|
stretch2D,
|
|
1622
3165
|
subFace,
|
|
1623
|
-
|
|
3166
|
+
B2 as supportExtrude,
|
|
3167
|
+
surfaceFromGrid,
|
|
3168
|
+
surfaceFromImage,
|
|
1624
3169
|
sweep,
|
|
3170
|
+
u3 as tagFaces,
|
|
1625
3171
|
tangentArc,
|
|
1626
|
-
|
|
3172
|
+
a52 as textBlueprints,
|
|
3173
|
+
a62 as textMetrics,
|
|
1627
3174
|
thicken,
|
|
1628
3175
|
threePointArc,
|
|
1629
3176
|
toBREP,
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
3177
|
+
t9 as toBufferGeometryData,
|
|
3178
|
+
k9 as toGroupedBufferGeometryData,
|
|
3179
|
+
l8 as toLineGeometryData,
|
|
3180
|
+
b as toOcVec,
|
|
1634
3181
|
toSVGPathD,
|
|
1635
3182
|
t as toVec2,
|
|
1636
3183
|
toVec3,
|
|
@@ -1639,44 +3186,44 @@ export {
|
|
|
1639
3186
|
translate,
|
|
1640
3187
|
translate2D,
|
|
1641
3188
|
W as translateDrawing,
|
|
1642
|
-
|
|
3189
|
+
t7 as translatePlane,
|
|
1643
3190
|
t2 as tryCatch,
|
|
1644
3191
|
n as tryCatchAsync,
|
|
1645
|
-
|
|
3192
|
+
C2 as twistExtrude,
|
|
1646
3193
|
typeCastError,
|
|
1647
|
-
|
|
3194
|
+
D2 as undoLast,
|
|
1648
3195
|
unwrap,
|
|
1649
3196
|
r2 as unwrapErr,
|
|
1650
3197
|
v as unwrapOr,
|
|
1651
3198
|
w2 as unwrapOrElse,
|
|
1652
|
-
|
|
3199
|
+
E as updateNode,
|
|
1653
3200
|
u4 as uvBounds,
|
|
1654
|
-
|
|
3201
|
+
h6 as uvCoordinates,
|
|
1655
3202
|
validationError,
|
|
1656
|
-
|
|
3203
|
+
v2 as vecAdd,
|
|
1657
3204
|
a3 as vecAngle,
|
|
1658
|
-
|
|
3205
|
+
b4 as vecCross,
|
|
1659
3206
|
vecDistance,
|
|
1660
3207
|
d as vecDot,
|
|
1661
3208
|
e as vecEquals,
|
|
1662
3209
|
vecIsZero,
|
|
1663
3210
|
g3 as vecLength,
|
|
1664
3211
|
h3 as vecLengthSq,
|
|
1665
|
-
|
|
3212
|
+
i3 as vecNegate,
|
|
1666
3213
|
vecNormalize,
|
|
1667
3214
|
k3 as vecProjectToPlane,
|
|
1668
3215
|
l3 as vecRepr,
|
|
1669
3216
|
m2 as vecRotate,
|
|
1670
3217
|
vecScale,
|
|
1671
|
-
|
|
3218
|
+
o as vecSub,
|
|
1672
3219
|
vertex,
|
|
1673
3220
|
vertexFinder,
|
|
1674
3221
|
vertexPosition,
|
|
1675
|
-
|
|
1676
|
-
|
|
3222
|
+
v5 as verticesOfEdge,
|
|
3223
|
+
walkAssembly,
|
|
1677
3224
|
wire,
|
|
1678
3225
|
wireFinder,
|
|
1679
|
-
|
|
3226
|
+
w6 as wiresOfFace,
|
|
1680
3227
|
w as withOcDir,
|
|
1681
3228
|
k as withOcPnt,
|
|
1682
3229
|
l as withOcVec,
|