brepjs 8.3.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/lib/Curve2D.d.ts.map +1 -1
- package/dist/2d.cjs +2 -2
- package/dist/2d.js +13 -13
- package/dist/{Blueprint-a3ukJMG4.cjs → Blueprint-BcbOBF-9.cjs} +17 -102
- package/dist/{Blueprint-CdVaHDSx.js → Blueprint-Cmh8lKc4.js} +35 -120
- package/dist/{boolean2D-pvPIs21j.cjs → boolean2D-CqacqjME.cjs} +24 -25
- package/dist/{boolean2D-DzA0STqC.js → boolean2D-D94Axs3i.js} +23 -24
- package/dist/{booleanFns-BcQUqjUu.js → booleanFns-DdjtpcM6.js} +306 -12
- package/dist/{booleanFns-Cd414V3l.cjs → booleanFns-NtKxkiXn.cjs} +299 -5
- package/dist/brepjs.cjs +1782 -68
- package/dist/brepjs.js +2030 -317
- package/dist/core/errors.d.ts +25 -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-DvPiz-VR.js → cornerFinder-BBOYfsXl.js} +1 -1
- package/dist/{cornerFinder-BdKtobgb.cjs → cornerFinder-Bqy8Lw2p.cjs} +1 -1
- package/dist/{curveFns-CyHyk29c.js → curveFns-B85Glnfo.js} +19 -17
- package/dist/{curveFns-B5EQsSwv.cjs → curveFns-BXCbASW-.cjs} +6 -4
- package/dist/{drawFns-CAAE4Z88.js → drawFns-B-gJ2WUc.js} +52 -23
- package/dist/{drawFns-Mr2pghU8.cjs → drawFns-CAmFEqd1.cjs} +68 -39
- package/dist/{errors-wGhcJMpB.js → errors-Coh_5_19.js} +35 -1
- package/dist/{errors-DK1VAdP4.cjs → errors-eRQu29oc.cjs} +35 -1
- package/dist/{faceFns-ub3CugDN.js → faceFns-CltrEfOo.js} +109 -12
- package/dist/{faceFns-D1Sqnlu6.cjs → faceFns-DcndPHWm.cjs} +103 -6
- package/dist/{helpers-CP2KrBZl.cjs → helpers-CC21GeAr.cjs} +8 -9
- package/dist/{helpers-r_e-u1JM.js → helpers-SksQIreB.js} +16 -17
- package/dist/index.d.ts +20 -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 +23 -0
- package/dist/kernel/hullOps.d.ts.map +1 -0
- package/dist/kernel/occtAdapter.d.ts +11 -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 +11 -0
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/{loft-PMRx9iMG.cjs → loft-BcyyvWCj.cjs} +28 -28
- package/dist/{loft-BHn7GKm8.js → loft-CJMPx1NQ.js} +16 -16
- package/dist/{measurement-BfhEneUl.js → measurement-ByOztLxb.js} +3 -3
- package/dist/{measurement-B06hNs89.cjs → measurement-DU3ry-0Q.cjs} +3 -3
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-BEvGVcym.js → meshFns-D2gLyLFt.js} +3 -3
- package/dist/{meshFns-CJV_k_EQ.cjs → meshFns-DawUwI3W.cjs} +3 -3
- package/dist/{occtBoundary-CoXB2xvx.js → occtBoundary-CWzWqBCm.js} +436 -7
- package/dist/{occtBoundary-BFAaUtA7.cjs → occtBoundary-DH2VO-rq.cjs} +431 -2
- 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-CYGNxn5D.cjs → operations-CdELWxgv.cjs} +7 -7
- package/dist/{operations-B314mytX.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-Z_ScEjmn.cjs → shapeFns-3RYtsUVY.cjs} +54 -21
- package/dist/{shapeFns-CWd_ASDV.js → shapeFns-4ioRrhih.js} +52 -19
- package/dist/{shapeTypes-UqVCIO_T.cjs → shapeTypes-CMjrTv36.cjs} +1 -1
- package/dist/{shapeTypes-BU2LKv2S.js → shapeTypes-D0vfRxWb.js} +13 -13
- package/dist/sketching.cjs +2 -2
- package/dist/sketching.js +2 -2
- package/dist/{curveBuilders-CN72XaIQ.js → surfaceBuilders-B7Jxob8g.js} +106 -13
- package/dist/{curveBuilders-Du03_Yyf.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/hullFns.d.ts +16 -0
- package/dist/topology/hullFns.d.ts.map +1 -0
- package/dist/topology/minkowskiFns.d.ts +20 -0
- package/dist/topology/minkowskiFns.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-A7-jUtHB.cjs → topology-D-nGjCzV.cjs} +19 -20
- package/dist/{topology-BupialMm.js → topology-DRP9zreU.js} +8 -9
- package/dist/topology.cjs +13 -14
- package/dist/topology.js +51 -52
- package/dist/{vectors-BhfKwL9J.js → vectors-CZV4ZrTz.js} +2 -2
- package/dist/{vectors-t1XG4LpL.cjs → vectors-DwFeX0Ja.cjs} +2 -2
- package/dist/vectors.cjs +2 -2
- package/dist/vectors.js +2 -2
- package/package.json +8 -7
- package/dist/cast-C107o5ow.cjs +0 -102
- package/dist/cast-D0OhP1nV.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,
|
|
4
|
-
import { O, a, c
|
|
5
|
-
import { c as castShape,
|
|
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-DzA0STqC.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-D0OhP1nV.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,1228 @@ 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
|
+
}
|
|
415
|
+
function validateNotNull$1(shape2, label) {
|
|
416
|
+
if (shape2.wrapped.IsNull()) {
|
|
417
|
+
return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `${label} is a null shape`));
|
|
418
|
+
}
|
|
419
|
+
return ok(void 0);
|
|
420
|
+
}
|
|
421
|
+
function hull(shapes, options = {}) {
|
|
422
|
+
if (shapes.length === 0) {
|
|
423
|
+
return err(
|
|
424
|
+
validationError(
|
|
425
|
+
BrepErrorCode.HULL_EMPTY_INPUT,
|
|
426
|
+
"hull: at least one shape is required",
|
|
427
|
+
void 0,
|
|
428
|
+
void 0,
|
|
429
|
+
"Provide one or more shapes to compute a convex hull"
|
|
430
|
+
)
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
for (const [i8, shape2] of shapes.entries()) {
|
|
434
|
+
const check = validateNotNull$1(shape2, `hull: shapes[${i8}]`);
|
|
435
|
+
if (isErr(check)) return check;
|
|
436
|
+
}
|
|
437
|
+
const tolerance = options.tolerance ?? 0.1;
|
|
438
|
+
try {
|
|
439
|
+
const kernel = getKernel();
|
|
440
|
+
const ocShapes = shapes.map((s6) => s6.wrapped);
|
|
441
|
+
const resultOc = kernel.hull(ocShapes, tolerance);
|
|
442
|
+
const cast = castShape(resultOc);
|
|
443
|
+
if (!isSolid(cast)) {
|
|
444
|
+
return err(
|
|
445
|
+
occtError(BrepErrorCode.HULL_NOT_3D, "Hull result is not a solid; input may be degenerate")
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
return ok(cast);
|
|
449
|
+
} catch (e8) {
|
|
450
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
451
|
+
if (raw.includes("coplanar") || raw.includes("fewer than") || raw.includes("degenerate")) {
|
|
452
|
+
return err(occtError(BrepErrorCode.HULL_DEGENERATE, `Hull degenerate: ${raw}`, e8));
|
|
453
|
+
}
|
|
454
|
+
return err(occtError(BrepErrorCode.HULL_FAILED, `Hull operation failed: ${raw}`, e8));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function detectSphere(shape2) {
|
|
458
|
+
const oc = getKernel().oc;
|
|
459
|
+
const faces = getFaces(shape2);
|
|
460
|
+
if (faces.length !== 1) return null;
|
|
461
|
+
const face2 = faces[0];
|
|
462
|
+
const r11 = gcWithScope();
|
|
463
|
+
const adaptor = r11(new oc.BRepAdaptor_Surface_2(face2.wrapped, true));
|
|
464
|
+
const surfType = adaptor.GetType();
|
|
465
|
+
if (surfType !== oc.GeomAbs_SurfaceType.GeomAbs_Sphere) return null;
|
|
466
|
+
const ocSphere = adaptor.Sphere();
|
|
467
|
+
const radius = ocSphere.Radius();
|
|
468
|
+
ocSphere.delete();
|
|
469
|
+
return radius;
|
|
470
|
+
}
|
|
471
|
+
function minkowskiSphere(shape2, radius, tolerance) {
|
|
472
|
+
const oc = getKernel().oc;
|
|
473
|
+
const r11 = gcWithScope();
|
|
474
|
+
try {
|
|
475
|
+
const offsetMaker = r11(new oc.BRepOffsetAPI_MakeOffsetShape());
|
|
476
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
477
|
+
offsetMaker.PerformByJoin(
|
|
478
|
+
shape2.wrapped,
|
|
479
|
+
radius,
|
|
480
|
+
tolerance,
|
|
481
|
+
oc.BRepOffset_Mode.BRepOffset_Skin,
|
|
482
|
+
false,
|
|
483
|
+
false,
|
|
484
|
+
oc.GeomAbs_JoinType.GeomAbs_Arc,
|
|
485
|
+
false,
|
|
486
|
+
progress
|
|
487
|
+
);
|
|
488
|
+
const resultShape = offsetMaker.Shape();
|
|
489
|
+
const wrapped = castShape(resultShape);
|
|
490
|
+
if (!isShape3D(wrapped)) {
|
|
491
|
+
wrapped[Symbol.dispose]();
|
|
492
|
+
return err(
|
|
493
|
+
typeCastError(
|
|
494
|
+
BrepErrorCode.MINKOWSKI_NOT_3D,
|
|
495
|
+
"Minkowski sphere offset did not produce a 3D shape"
|
|
496
|
+
)
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
return ok(wrapped);
|
|
500
|
+
} catch (e8) {
|
|
501
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
502
|
+
return err(
|
|
503
|
+
occtError(BrepErrorCode.MINKOWSKI_FAILED, `Minkowski sphere offset failed: ${raw}`, e8, {
|
|
504
|
+
operation: "minkowski",
|
|
505
|
+
fastPath: "sphere"
|
|
506
|
+
})
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function minkowskiGeneral(shape2, tool, _tolerance) {
|
|
511
|
+
const oc = getKernel().oc;
|
|
512
|
+
try {
|
|
513
|
+
const shapeVerts = getVertices(shape2);
|
|
514
|
+
const toolVerts = getVertices(tool);
|
|
515
|
+
if (shapeVerts.length === 0 || toolVerts.length === 0) {
|
|
516
|
+
return err(
|
|
517
|
+
occtError(
|
|
518
|
+
BrepErrorCode.MINKOWSKI_FAILED,
|
|
519
|
+
"Minkowski sum: one or both shapes have no vertices",
|
|
520
|
+
void 0,
|
|
521
|
+
{
|
|
522
|
+
operation: "minkowski"
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
const sumPoints = [];
|
|
528
|
+
for (const sv of shapeVerts) {
|
|
529
|
+
const r1 = gcWithScope();
|
|
530
|
+
const pa = r1(oc.BRep_Tool.Pnt(sv.wrapped));
|
|
531
|
+
const ax = pa.X(), ay = pa.Y(), az = pa.Z();
|
|
532
|
+
for (const tv of toolVerts) {
|
|
533
|
+
const r22 = gcWithScope();
|
|
534
|
+
const pb = r22(oc.BRep_Tool.Pnt(tv.wrapped));
|
|
535
|
+
const bx = pb.X(), by = pb.Y(), bz = pb.Z();
|
|
536
|
+
sumPoints.push({ x: ax + bx, y: ay + by, z: az + bz });
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
const kernel = getKernel();
|
|
540
|
+
const hullShape = kernel.hullFromPoints(sumPoints, _tolerance);
|
|
541
|
+
const wrapped = castShape(hullShape);
|
|
542
|
+
if (!isShape3D(wrapped)) {
|
|
543
|
+
wrapped[Symbol.dispose]();
|
|
544
|
+
return err(
|
|
545
|
+
typeCastError(BrepErrorCode.MINKOWSKI_NOT_3D, "Minkowski hull did not produce a 3D shape")
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
return ok(wrapped);
|
|
549
|
+
} catch (e8) {
|
|
550
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
551
|
+
return err(
|
|
552
|
+
occtError(BrepErrorCode.MINKOWSKI_FAILED, `Minkowski general path failed: ${raw}`, e8, {
|
|
553
|
+
operation: "minkowski"
|
|
554
|
+
})
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
function minkowski(shape2, tool, options = {}) {
|
|
559
|
+
const { tolerance = 1e-6 } = options;
|
|
560
|
+
if (shape2.wrapped.IsNull()) {
|
|
561
|
+
return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, "minkowski: shape is a null shape"));
|
|
562
|
+
}
|
|
563
|
+
if (tool.wrapped.IsNull()) {
|
|
564
|
+
return err(
|
|
565
|
+
validationError(BrepErrorCode.MINKOWSKI_NULL_TOOL, "minkowski: tool is a null shape")
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
if (!isShape3D(shape2) || !isShape3D(tool)) {
|
|
569
|
+
return err(
|
|
570
|
+
validationError(BrepErrorCode.MINKOWSKI_NOT_3D, "minkowski: both shape and tool must be 3D")
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
const sphereRadius = detectSphere(tool);
|
|
574
|
+
if (sphereRadius !== null) {
|
|
575
|
+
return minkowskiSphere(shape2, sphereRadius, tolerance);
|
|
576
|
+
}
|
|
577
|
+
return minkowskiGeneral(shape2, tool, tolerance);
|
|
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
|
+
}
|
|
162
1382
|
function checkInterference(shape1, shape2, tolerance = 1e-6) {
|
|
163
1383
|
if (shape1.wrapped.IsNull()) {
|
|
164
1384
|
return err(
|
|
@@ -186,29 +1406,481 @@ function checkInterference(shape1, shape2, tolerance = 1e-6) {
|
|
|
186
1406
|
}
|
|
187
1407
|
function checkAllInterferences(shapes, tolerance = 1e-6) {
|
|
188
1408
|
const pairs = [];
|
|
189
|
-
shapes.forEach((si,
|
|
190
|
-
for (let
|
|
191
|
-
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));
|
|
192
1412
|
if (result.hasInterference) {
|
|
193
|
-
pairs.push({ i:
|
|
1413
|
+
pairs.push({ i: i8, j: j8, result });
|
|
194
1414
|
}
|
|
195
1415
|
}
|
|
196
1416
|
});
|
|
197
1417
|
return pairs;
|
|
198
1418
|
}
|
|
199
|
-
function
|
|
200
|
-
|
|
201
|
-
|
|
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
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
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();
|
|
202
1843
|
}
|
|
203
|
-
return s5;
|
|
204
1844
|
}
|
|
205
|
-
function
|
|
206
|
-
|
|
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);
|
|
207
1879
|
}
|
|
208
1880
|
function box(width, depth, height, options) {
|
|
209
1881
|
const oc = getKernel().oc;
|
|
210
|
-
const
|
|
211
|
-
const maker =
|
|
1882
|
+
const r11 = gcWithScope();
|
|
1883
|
+
const maker = r11(new oc.BRepPrimAPI_MakeBox_2(width, depth, height));
|
|
212
1884
|
const solid2 = createSolid(maker.Solid());
|
|
213
1885
|
const center = options?.at ?? (options?.centered ? [0, 0, 0] : void 0);
|
|
214
1886
|
if (center) {
|
|
@@ -309,14 +1981,14 @@ function tangentArc(startPoint, startTgt, endPoint) {
|
|
|
309
1981
|
function wire(listOfEdges) {
|
|
310
1982
|
return assembleWire(listOfEdges);
|
|
311
1983
|
}
|
|
312
|
-
function face(
|
|
313
|
-
return makeFace(
|
|
1984
|
+
function face(w7, holes) {
|
|
1985
|
+
return makeFace(w7, holes);
|
|
314
1986
|
}
|
|
315
|
-
function filledFace(
|
|
316
|
-
return makeNonPlanarFace(
|
|
1987
|
+
function filledFace(w7) {
|
|
1988
|
+
return makeNonPlanarFace(w7);
|
|
317
1989
|
}
|
|
318
|
-
function subFace(originFace,
|
|
319
|
-
return makeNewFaceWithinFace(originFace,
|
|
1990
|
+
function subFace(originFace, w7) {
|
|
1991
|
+
return makeNewFaceWithinFace(originFace, w7);
|
|
320
1992
|
}
|
|
321
1993
|
function polygon(points) {
|
|
322
1994
|
return makePolygon(points);
|
|
@@ -330,14 +2002,14 @@ function compound(shapeArray) {
|
|
|
330
2002
|
function solid(facesOrShells) {
|
|
331
2003
|
return makeSolid(facesOrShells);
|
|
332
2004
|
}
|
|
333
|
-
function offsetFace(
|
|
334
|
-
return makeOffset(
|
|
2005
|
+
function offsetFace(f12, distance, tolerance) {
|
|
2006
|
+
return makeOffset(f12, distance, tolerance);
|
|
335
2007
|
}
|
|
336
2008
|
function sewShells(facesOrShells, ignoreType) {
|
|
337
2009
|
return weldShellsAndFaces(facesOrShells, ignoreType);
|
|
338
2010
|
}
|
|
339
|
-
function addHoles(
|
|
340
|
-
return addHolesInFace(
|
|
2011
|
+
function addHoles(f12, holes) {
|
|
2012
|
+
return addHolesInFace(f12, holes);
|
|
341
2013
|
}
|
|
342
2014
|
function validateNotNull(shape2, label) {
|
|
343
2015
|
if (shape2.wrapped.IsNull()) {
|
|
@@ -350,18 +2022,20 @@ function thicken$1(shape2, thickness) {
|
|
|
350
2022
|
if (isErr(check)) return check;
|
|
351
2023
|
try {
|
|
352
2024
|
const oc = getKernel().oc;
|
|
353
|
-
const
|
|
354
|
-
const builder =
|
|
2025
|
+
const r11 = gcWithScope();
|
|
2026
|
+
const builder = r11(new oc.BRepOffsetAPI_MakeThickSolid());
|
|
355
2027
|
builder.MakeThickSolidBySimple(shape2.wrapped, thickness);
|
|
356
|
-
const progress =
|
|
2028
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
357
2029
|
builder.Build(progress);
|
|
358
2030
|
const resultOc = builder.Shape();
|
|
359
2031
|
const cast = castShape(resultOc);
|
|
360
2032
|
propagateOrigins(builder, [shape2], cast);
|
|
2033
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2034
|
+
propagateColors(builder, [shape2], cast);
|
|
361
2035
|
return ok(cast);
|
|
362
|
-
} catch (
|
|
363
|
-
const raw =
|
|
364
|
-
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));
|
|
365
2039
|
}
|
|
366
2040
|
}
|
|
367
2041
|
function fillet$1(shape2, edges, radius) {
|
|
@@ -403,8 +2077,8 @@ function fillet$1(shape2, edges, radius) {
|
|
|
403
2077
|
}
|
|
404
2078
|
try {
|
|
405
2079
|
const oc = getKernel().oc;
|
|
406
|
-
const
|
|
407
|
-
const builder =
|
|
2080
|
+
const r11 = gcWithScope();
|
|
2081
|
+
const builder = r11(
|
|
408
2082
|
new oc.BRepFilletAPI_MakeFillet(shape2.wrapped, oc.ChFi3d_FilletShape.ChFi3d_Rational)
|
|
409
2083
|
);
|
|
410
2084
|
for (const edge of selectedEdges) {
|
|
@@ -422,11 +2096,13 @@ function fillet$1(shape2, edges, radius) {
|
|
|
422
2096
|
return err(occtError("FILLET_RESULT_NOT_3D", "Fillet result is not a 3D shape"));
|
|
423
2097
|
}
|
|
424
2098
|
propagateOrigins(builder, [shape2], cast);
|
|
2099
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2100
|
+
propagateColors(builder, [shape2], cast);
|
|
425
2101
|
return ok(cast);
|
|
426
|
-
} catch (
|
|
427
|
-
const raw =
|
|
2102
|
+
} catch (e8) {
|
|
2103
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
428
2104
|
return err(
|
|
429
|
-
occtError("FILLET_FAILED", `Fillet operation failed: ${raw}`,
|
|
2105
|
+
occtError("FILLET_FAILED", `Fillet operation failed: ${raw}`, e8, {
|
|
430
2106
|
operation: "fillet",
|
|
431
2107
|
edgeCount: selectedEdges.length,
|
|
432
2108
|
radius
|
|
@@ -493,15 +2169,15 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
493
2169
|
return edgeFaceMap;
|
|
494
2170
|
};
|
|
495
2171
|
const oc = getKernel().oc;
|
|
496
|
-
const
|
|
497
|
-
const builder =
|
|
2172
|
+
const r11 = gcWithScope();
|
|
2173
|
+
const builder = r11(new oc.BRepFilletAPI_MakeChamfer(shape2.wrapped));
|
|
498
2174
|
let edgeFaceMap = null;
|
|
499
2175
|
for (const edge of selectedEdges) {
|
|
500
|
-
const
|
|
501
|
-
if (typeof
|
|
502
|
-
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);
|
|
503
2179
|
} else {
|
|
504
|
-
const [d1, d22] =
|
|
2180
|
+
const [d1, d22] = d9;
|
|
505
2181
|
if (d1 > 0 && d22 > 0) {
|
|
506
2182
|
const face2 = getEdgeFaceMap().get(edge.wrapped.HashCode(2147483647));
|
|
507
2183
|
if (face2) {
|
|
@@ -516,11 +2192,13 @@ function chamfer$1(shape2, edges, distance) {
|
|
|
516
2192
|
return err(occtError("CHAMFER_RESULT_NOT_3D", "Chamfer result is not a 3D shape"));
|
|
517
2193
|
}
|
|
518
2194
|
propagateOrigins(builder, [shape2], cast);
|
|
2195
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2196
|
+
propagateColors(builder, [shape2], cast);
|
|
519
2197
|
return ok(cast);
|
|
520
|
-
} catch (
|
|
521
|
-
const raw =
|
|
2198
|
+
} catch (e8) {
|
|
2199
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
522
2200
|
return err(
|
|
523
|
-
occtError("CHAMFER_FAILED", `Chamfer operation failed: ${raw}`,
|
|
2201
|
+
occtError("CHAMFER_FAILED", `Chamfer operation failed: ${raw}`, e8, {
|
|
524
2202
|
operation: "chamfer",
|
|
525
2203
|
edgeCount: selectedEdges.length,
|
|
526
2204
|
distance
|
|
@@ -539,13 +2217,13 @@ function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
|
|
|
539
2217
|
}
|
|
540
2218
|
try {
|
|
541
2219
|
const oc = getKernel().oc;
|
|
542
|
-
const
|
|
543
|
-
const facesToRemove =
|
|
2220
|
+
const r11 = gcWithScope();
|
|
2221
|
+
const facesToRemove = r11(new oc.TopTools_ListOfShape_1());
|
|
544
2222
|
for (const face2 of faces) {
|
|
545
2223
|
facesToRemove.Append_1(face2.wrapped);
|
|
546
2224
|
}
|
|
547
|
-
const progress =
|
|
548
|
-
const builder =
|
|
2225
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
2226
|
+
const builder = r11(new oc.BRepOffsetAPI_MakeThickSolid());
|
|
549
2227
|
builder.MakeThickSolidByJoin(
|
|
550
2228
|
shape2.wrapped,
|
|
551
2229
|
facesToRemove,
|
|
@@ -564,11 +2242,13 @@ function shell$1(shape2, faces, thickness, tolerance = 1e-3) {
|
|
|
564
2242
|
return err(occtError("SHELL_RESULT_NOT_3D", "Shell result is not a 3D shape"));
|
|
565
2243
|
}
|
|
566
2244
|
propagateOrigins(builder, [shape2], cast);
|
|
2245
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2246
|
+
propagateColors(builder, [shape2], cast);
|
|
567
2247
|
return ok(cast);
|
|
568
|
-
} catch (
|
|
569
|
-
const raw =
|
|
2248
|
+
} catch (e8) {
|
|
2249
|
+
const raw = e8 instanceof Error ? e8.message : String(e8);
|
|
570
2250
|
return err(
|
|
571
|
-
occtError("SHELL_FAILED", `Shell operation failed: ${raw}`,
|
|
2251
|
+
occtError("SHELL_FAILED", `Shell operation failed: ${raw}`, e8, {
|
|
572
2252
|
operation: "shell",
|
|
573
2253
|
faceCount: faces.length,
|
|
574
2254
|
thickness
|
|
@@ -584,9 +2264,9 @@ function offset$1(shape2, distance, tolerance = 1e-6) {
|
|
|
584
2264
|
}
|
|
585
2265
|
try {
|
|
586
2266
|
const oc = getKernel().oc;
|
|
587
|
-
const
|
|
588
|
-
const progress =
|
|
589
|
-
const builder =
|
|
2267
|
+
const r11 = gcWithScope();
|
|
2268
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
2269
|
+
const builder = r11(new oc.BRepOffsetAPI_MakeOffsetShape());
|
|
590
2270
|
builder.PerformByJoin(
|
|
591
2271
|
shape2.wrapped,
|
|
592
2272
|
distance,
|
|
@@ -604,10 +2284,12 @@ function offset$1(shape2, distance, tolerance = 1e-6) {
|
|
|
604
2284
|
return err(occtError("OFFSET_RESULT_NOT_3D", "Offset result is not a 3D shape"));
|
|
605
2285
|
}
|
|
606
2286
|
propagateOrigins(builder, [shape2], cast);
|
|
2287
|
+
propagateFaceTags(builder, [shape2], cast);
|
|
2288
|
+
propagateColors(builder, [shape2], cast);
|
|
607
2289
|
return ok(cast);
|
|
608
|
-
} catch (
|
|
609
|
-
const raw =
|
|
610
|
-
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));
|
|
611
2293
|
}
|
|
612
2294
|
}
|
|
613
2295
|
function translate(shape2, v7) {
|
|
@@ -633,18 +2315,21 @@ function applyMatrix(shape2, matrix) {
|
|
|
633
2315
|
function transformCopy(shape2, composed) {
|
|
634
2316
|
return transformCopy$1(resolve(shape2), composed);
|
|
635
2317
|
}
|
|
636
|
-
function fuse(
|
|
637
|
-
return fuse$1(resolve(
|
|
2318
|
+
function fuse(a9, b11, options) {
|
|
2319
|
+
return fuse$1(resolve(a9), resolve(b11), options);
|
|
638
2320
|
}
|
|
639
2321
|
function cut(base, tool, options) {
|
|
640
2322
|
return cut$1(resolve(base), resolve(tool), options);
|
|
641
2323
|
}
|
|
642
|
-
function intersect(
|
|
643
|
-
return intersect$1(resolve(
|
|
2324
|
+
function intersect(a9, b11, options) {
|
|
2325
|
+
return intersect$1(resolve(a9), resolve(b11), options);
|
|
644
2326
|
}
|
|
645
2327
|
function section(shape2, plane, options) {
|
|
646
2328
|
return section$1(resolve(shape2), plane, options);
|
|
647
2329
|
}
|
|
2330
|
+
function sectionToFace(shape2, plane, options) {
|
|
2331
|
+
return sectionToFace$1(resolve(shape2), plane, options);
|
|
2332
|
+
}
|
|
648
2333
|
function split(shape2, tools) {
|
|
649
2334
|
return split$1(resolve(shape2), tools);
|
|
650
2335
|
}
|
|
@@ -689,24 +2374,24 @@ function normalizeChamferDistance(distance) {
|
|
|
689
2374
|
return { mode: "standard", distance };
|
|
690
2375
|
}
|
|
691
2376
|
function fillet(shape2, edgesOrRadius, maybeRadius) {
|
|
692
|
-
const
|
|
2377
|
+
const s6 = resolve(shape2);
|
|
693
2378
|
let edges;
|
|
694
2379
|
let radius;
|
|
695
2380
|
if (maybeRadius !== void 0) {
|
|
696
|
-
edges = resolveEdges(edgesOrRadius,
|
|
2381
|
+
edges = resolveEdges(edgesOrRadius, s6);
|
|
697
2382
|
radius = maybeRadius;
|
|
698
2383
|
} else {
|
|
699
2384
|
edges = void 0;
|
|
700
2385
|
radius = edgesOrRadius;
|
|
701
2386
|
}
|
|
702
|
-
return fillet$1(
|
|
2387
|
+
return fillet$1(s6, edges, normalizeFilletRadius(radius));
|
|
703
2388
|
}
|
|
704
2389
|
function chamfer(shape2, edgesOrDistance, maybeDistance) {
|
|
705
|
-
const
|
|
2390
|
+
const s6 = resolve(shape2);
|
|
706
2391
|
let edges;
|
|
707
2392
|
let distance;
|
|
708
2393
|
if (maybeDistance !== void 0) {
|
|
709
|
-
edges = resolveEdges(edgesOrDistance,
|
|
2394
|
+
edges = resolveEdges(edgesOrDistance, s6);
|
|
710
2395
|
distance = maybeDistance;
|
|
711
2396
|
} else {
|
|
712
2397
|
edges = void 0;
|
|
@@ -714,20 +2399,20 @@ function chamfer(shape2, edgesOrDistance, maybeDistance) {
|
|
|
714
2399
|
}
|
|
715
2400
|
const normalized = normalizeChamferDistance(distance);
|
|
716
2401
|
if (normalized.mode === "distAngle") {
|
|
717
|
-
const selectedEdges = edges ?? getEdges(
|
|
2402
|
+
const selectedEdges = edges ?? getEdges(s6);
|
|
718
2403
|
return chamferDistAngle(
|
|
719
|
-
|
|
2404
|
+
s6,
|
|
720
2405
|
[...selectedEdges],
|
|
721
2406
|
normalized.distance,
|
|
722
2407
|
normalized.angle
|
|
723
2408
|
);
|
|
724
2409
|
}
|
|
725
|
-
return chamfer$1(
|
|
2410
|
+
return chamfer$1(s6, edges, normalized.distance);
|
|
726
2411
|
}
|
|
727
2412
|
function shell(shape2, faces, thickness, options) {
|
|
728
|
-
const
|
|
729
|
-
const resolvedFaces = resolveFaces(faces,
|
|
730
|
-
return shell$1(
|
|
2413
|
+
const s6 = resolve(shape2);
|
|
2414
|
+
const resolvedFaces = resolveFaces(faces, s6);
|
|
2415
|
+
return shell$1(s6, resolvedFaces, thickness, options?.tolerance);
|
|
731
2416
|
}
|
|
732
2417
|
function offset(shape2, distance, options) {
|
|
733
2418
|
return offset$1(resolve(shape2), distance, options?.tolerance);
|
|
@@ -767,22 +2452,22 @@ function loft$1(wires, { ruled = true, startPoint, endPoint } = {}, returnShell
|
|
|
767
2452
|
return err(validationError("LOFT_EMPTY", "Loft requires at least one wire or start/end point"));
|
|
768
2453
|
}
|
|
769
2454
|
const oc = getKernel().oc;
|
|
770
|
-
const
|
|
771
|
-
const builder =
|
|
2455
|
+
const r11 = gcWithScope();
|
|
2456
|
+
const builder = r11(new oc.BRepOffsetAPI_ThruSections(!returnShell, ruled, 1e-6));
|
|
772
2457
|
if (startPoint) {
|
|
773
|
-
const pnt =
|
|
774
|
-
const vMaker =
|
|
2458
|
+
const pnt = r11(toOcPnt(toVec3(startPoint)));
|
|
2459
|
+
const vMaker = r11(new oc.BRepBuilderAPI_MakeVertex(pnt));
|
|
775
2460
|
builder.AddVertex(vMaker.Vertex());
|
|
776
2461
|
}
|
|
777
|
-
for (const
|
|
778
|
-
builder.AddWire(
|
|
2462
|
+
for (const w7 of wires) {
|
|
2463
|
+
builder.AddWire(w7.wrapped);
|
|
779
2464
|
}
|
|
780
2465
|
if (endPoint) {
|
|
781
|
-
const pnt =
|
|
782
|
-
const vMaker =
|
|
2466
|
+
const pnt = r11(toOcPnt(toVec3(endPoint)));
|
|
2467
|
+
const vMaker = r11(new oc.BRepBuilderAPI_MakeVertex(pnt));
|
|
783
2468
|
builder.AddVertex(vMaker.Vertex());
|
|
784
2469
|
}
|
|
785
|
-
const progress =
|
|
2470
|
+
const progress = r11(new oc.Message_ProgressRange_1());
|
|
786
2471
|
builder.Build(progress);
|
|
787
2472
|
if (!builder.IsDone()) {
|
|
788
2473
|
return err(occtError("LOFT_FAILED", "Loft operation failed"));
|
|
@@ -794,9 +2479,9 @@ function loft$1(wires, { ruled = true, startPoint, endPoint } = {}, returnShell
|
|
|
794
2479
|
return ok(result);
|
|
795
2480
|
}
|
|
796
2481
|
function extrude(face2, height) {
|
|
797
|
-
const
|
|
2482
|
+
const f12 = resolve(face2);
|
|
798
2483
|
const vec = typeof height === "number" ? [0, 0, height] : height;
|
|
799
|
-
return extrude$1(
|
|
2484
|
+
return extrude$1(f12, vec);
|
|
800
2485
|
}
|
|
801
2486
|
function revolve(face2, options) {
|
|
802
2487
|
const pivotPoint = options?.at ?? [0, 0, 0];
|
|
@@ -808,7 +2493,7 @@ function revolve(face2, options) {
|
|
|
808
2493
|
);
|
|
809
2494
|
}
|
|
810
2495
|
function loft(wires, options) {
|
|
811
|
-
const resolvedWires = wires.map((
|
|
2496
|
+
const resolvedWires = wires.map((w7) => resolve(w7));
|
|
812
2497
|
return loft$1(resolvedWires, options);
|
|
813
2498
|
}
|
|
814
2499
|
function resolveTargetFace(shape2, faceSpec) {
|
|
@@ -819,12 +2504,12 @@ function resolveTargetFace(shape2, faceSpec) {
|
|
|
819
2504
|
}
|
|
820
2505
|
let best = faces[0];
|
|
821
2506
|
let bestZ = faceCenter(best)[2];
|
|
822
|
-
for (let
|
|
823
|
-
const
|
|
824
|
-
const
|
|
825
|
-
if (
|
|
826
|
-
best =
|
|
827
|
-
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;
|
|
828
2513
|
}
|
|
829
2514
|
}
|
|
830
2515
|
return best;
|
|
@@ -846,7 +2531,7 @@ function toWire(profile) {
|
|
|
846
2531
|
return profile;
|
|
847
2532
|
}
|
|
848
2533
|
function drill(shape2, options) {
|
|
849
|
-
const
|
|
2534
|
+
const s6 = resolve(shape2);
|
|
850
2535
|
const { at, radius, axis: rawAxis } = options;
|
|
851
2536
|
const axis = rawAxis ?? [0, 0, 1];
|
|
852
2537
|
if (radius <= 0) {
|
|
@@ -859,7 +2544,7 @@ function drill(shape2, options) {
|
|
|
859
2544
|
const pos = at.length === 2 ? [at[0], at[1], 0] : [at[0], at[1], at[2]];
|
|
860
2545
|
let depth = options.depth;
|
|
861
2546
|
if (depth === void 0) {
|
|
862
|
-
const b11 = getBounds(
|
|
2547
|
+
const b11 = getBounds(s6);
|
|
863
2548
|
const dx = b11.xMax - b11.xMin;
|
|
864
2549
|
const dy = b11.yMax - b11.yMin;
|
|
865
2550
|
const dz = b11.zMax - b11.zMin;
|
|
@@ -868,49 +2553,49 @@ function drill(shape2, options) {
|
|
|
868
2553
|
const cyl = makeCylinder(radius, depth, pos, dir);
|
|
869
2554
|
const startOffset = options.depth === void 0 ? vecScale(dir, -depth / 2) : [0, 0, 0];
|
|
870
2555
|
const tool = startOffset[0] !== 0 || startOffset[1] !== 0 || startOffset[2] !== 0 ? translate$1(cyl, startOffset) : cyl;
|
|
871
|
-
return cut$1(
|
|
2556
|
+
return cut$1(s6, tool);
|
|
872
2557
|
}
|
|
873
2558
|
function pocket(shape2, options) {
|
|
874
|
-
const
|
|
2559
|
+
const s6 = resolve(shape2);
|
|
875
2560
|
const { profile, depth } = options;
|
|
876
2561
|
if (depth <= 0) {
|
|
877
2562
|
return err(validationError("POCKET_INVALID_DEPTH", "Pocket depth must be positive"));
|
|
878
2563
|
}
|
|
879
|
-
const targetFace = resolveTargetFace(
|
|
2564
|
+
const targetFace = resolveTargetFace(s6, options.face);
|
|
880
2565
|
const normal = normalAt(targetFace);
|
|
881
|
-
const
|
|
882
|
-
const faceResult = makeFace(
|
|
2566
|
+
const w7 = toWire(profile);
|
|
2567
|
+
const faceResult = makeFace(w7);
|
|
883
2568
|
if (isErr(faceResult)) return faceResult;
|
|
884
2569
|
const extDir = vecScale(vecNormalize(normal), -depth);
|
|
885
2570
|
const toolResult = extrude$1(faceResult.value, extDir);
|
|
886
2571
|
if (isErr(toolResult)) return toolResult;
|
|
887
|
-
return cut$1(
|
|
2572
|
+
return cut$1(s6, toolResult.value);
|
|
888
2573
|
}
|
|
889
2574
|
function boss(shape2, options) {
|
|
890
|
-
const
|
|
2575
|
+
const s6 = resolve(shape2);
|
|
891
2576
|
const { profile, height } = options;
|
|
892
2577
|
if (height <= 0) {
|
|
893
2578
|
return err(validationError("BOSS_INVALID_HEIGHT", "Boss height must be positive"));
|
|
894
2579
|
}
|
|
895
|
-
const targetFace = resolveTargetFace(
|
|
2580
|
+
const targetFace = resolveTargetFace(s6, options.face);
|
|
896
2581
|
const normal = normalAt(targetFace);
|
|
897
|
-
const
|
|
898
|
-
const faceResult = makeFace(
|
|
2582
|
+
const w7 = toWire(profile);
|
|
2583
|
+
const faceResult = makeFace(w7);
|
|
899
2584
|
if (isErr(faceResult)) return faceResult;
|
|
900
2585
|
const extDir = vecScale(vecNormalize(normal), height);
|
|
901
2586
|
const toolResult = extrude$1(faceResult.value, extDir);
|
|
902
2587
|
if (isErr(toolResult)) return toolResult;
|
|
903
|
-
return fuse$1(
|
|
2588
|
+
return fuse$1(s6, toolResult.value);
|
|
904
2589
|
}
|
|
905
2590
|
function mirrorJoin(shape2, options) {
|
|
906
|
-
const
|
|
2591
|
+
const s6 = resolve(shape2);
|
|
907
2592
|
const normal = options?.normal ?? [1, 0, 0];
|
|
908
2593
|
const planeOrigin = options?.at;
|
|
909
|
-
const mirrored = mirror$1(
|
|
910
|
-
return fuse$1(
|
|
2594
|
+
const mirrored = mirror$1(s6, normal, planeOrigin);
|
|
2595
|
+
return fuse$1(s6, mirrored);
|
|
911
2596
|
}
|
|
912
2597
|
function rectangularPattern(shape2, options) {
|
|
913
|
-
const
|
|
2598
|
+
const s6 = resolve(shape2);
|
|
914
2599
|
const { xDir, xCount, xSpacing, yDir, yCount, ySpacing } = options;
|
|
915
2600
|
if (xCount < 1 || yCount < 1) {
|
|
916
2601
|
return err(validationError("PATTERN_INVALID_COUNT", "Pattern counts must be at least 1"));
|
|
@@ -921,10 +2606,10 @@ function rectangularPattern(shape2, options) {
|
|
|
921
2606
|
if (vecIsZero(yDir)) {
|
|
922
2607
|
return err(validationError("PATTERN_ZERO_DIRECTION", "Y direction cannot be zero"));
|
|
923
2608
|
}
|
|
924
|
-
if (xCount === 1 && yCount === 1) return ok(
|
|
2609
|
+
if (xCount === 1 && yCount === 1) return ok(s6);
|
|
925
2610
|
const xNorm = vecNormalize(xDir);
|
|
926
2611
|
const yNorm = vecNormalize(yDir);
|
|
927
|
-
const copies = [
|
|
2612
|
+
const copies = [s6];
|
|
928
2613
|
for (let xi = 0; xi < xCount; xi++) {
|
|
929
2614
|
for (let yi = 0; yi < yCount; yi++) {
|
|
930
2615
|
if (xi === 0 && yi === 0) continue;
|
|
@@ -933,7 +2618,7 @@ function rectangularPattern(shape2, options) {
|
|
|
933
2618
|
xNorm[1] * xSpacing * xi + yNorm[1] * ySpacing * yi,
|
|
934
2619
|
xNorm[2] * xSpacing * xi + yNorm[2] * ySpacing * yi
|
|
935
2620
|
];
|
|
936
|
-
copies.push(translate$1(
|
|
2621
|
+
copies.push(translate$1(s6, offset2));
|
|
937
2622
|
}
|
|
938
2623
|
}
|
|
939
2624
|
return fuseAll(copies);
|
|
@@ -974,12 +2659,12 @@ function createWrappedBase(val) {
|
|
|
974
2659
|
mirror: (opts) => wrapAny(mirror(val, opts)),
|
|
975
2660
|
scale: (factor, opts) => wrapAny(scale(val, factor, opts)),
|
|
976
2661
|
applyMatrix: (matrix) => wrapAny(applyMatrix(val, matrix)),
|
|
977
|
-
moveX: (
|
|
978
|
-
moveY: (
|
|
979
|
-
moveZ: (
|
|
980
|
-
rotateX: (
|
|
981
|
-
rotateY: (
|
|
982
|
-
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] })),
|
|
983
2668
|
bounds: () => getBounds(val),
|
|
984
2669
|
describe: () => describe(val),
|
|
985
2670
|
clone: () => wrapAny(clone(val)),
|
|
@@ -1058,13 +2743,13 @@ function createWrappedCurve(val) {
|
|
|
1058
2743
|
length: () => curveLength(val),
|
|
1059
2744
|
startPoint: () => curveStartPoint(val),
|
|
1060
2745
|
endPoint: () => curveEndPoint(val),
|
|
1061
|
-
pointAt: (
|
|
1062
|
-
tangentAt: (
|
|
2746
|
+
pointAt: (t11) => curvePointAt(val, t11),
|
|
2747
|
+
tangentAt: (t11) => curveTangentAt(val, t11),
|
|
1063
2748
|
isClosed: () => curveIsClosed(val),
|
|
1064
2749
|
sweep(spine, opts) {
|
|
1065
2750
|
if (!isWire(val)) throw new Error("sweep requires a Wire");
|
|
1066
|
-
const
|
|
1067
|
-
const result = unwrapOrThrow(sweep(
|
|
2751
|
+
const w7 = val;
|
|
2752
|
+
const result = unwrapOrThrow(sweep(w7, resolve(spine), opts));
|
|
1068
2753
|
const shape3D = Array.isArray(result) ? result[0] : result;
|
|
1069
2754
|
return wrap3D(shape3D);
|
|
1070
2755
|
}
|
|
@@ -1093,15 +2778,15 @@ function wrapAny(val) {
|
|
|
1093
2778
|
function wrap3D(val) {
|
|
1094
2779
|
return createWrapped3D(val);
|
|
1095
2780
|
}
|
|
1096
|
-
function shape(
|
|
1097
|
-
if (
|
|
1098
|
-
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());
|
|
1099
2784
|
}
|
|
1100
|
-
if (
|
|
1101
|
-
if (isFace(
|
|
1102
|
-
if (isShape3D(
|
|
1103
|
-
if (isEdge(
|
|
1104
|
-
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);
|
|
1105
2790
|
}
|
|
1106
2791
|
throw new Error("shape() requires a Sketch or branded shape type");
|
|
1107
2792
|
}
|
|
@@ -1109,8 +2794,8 @@ export {
|
|
|
1109
2794
|
B3 as BaseSketcher2d,
|
|
1110
2795
|
B as Blueprint,
|
|
1111
2796
|
a5 as BlueprintSketcher,
|
|
1112
|
-
|
|
1113
|
-
|
|
2797
|
+
e2 as Blueprints,
|
|
2798
|
+
d2 as BoundingBox2d,
|
|
1114
2799
|
BrepBugError,
|
|
1115
2800
|
BrepErrorCode,
|
|
1116
2801
|
BrepWrapperError,
|
|
@@ -1127,19 +2812,20 @@ export {
|
|
|
1127
2812
|
R as RAD2DEG,
|
|
1128
2813
|
S as Sketch,
|
|
1129
2814
|
S2 as Sketcher,
|
|
1130
|
-
|
|
2815
|
+
b8 as Sketches,
|
|
1131
2816
|
a4 as addChild,
|
|
1132
2817
|
addHoles,
|
|
1133
|
-
|
|
2818
|
+
addMate,
|
|
2819
|
+
b7 as addStep,
|
|
1134
2820
|
a8 as adjacentFaces,
|
|
1135
2821
|
a as andThen,
|
|
1136
|
-
|
|
2822
|
+
j6 as applyGlue,
|
|
1137
2823
|
applyMatrix,
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
2824
|
+
j3 as approximateCurve,
|
|
2825
|
+
l9 as asTopo,
|
|
2826
|
+
b9 as autoHeal,
|
|
2827
|
+
r4 as axis2d,
|
|
2828
|
+
b6 as basicFaceExtrusion,
|
|
1143
2829
|
bezier,
|
|
1144
2830
|
blueprintToDXF,
|
|
1145
2831
|
boss,
|
|
@@ -1148,7 +2834,7 @@ export {
|
|
|
1148
2834
|
bug,
|
|
1149
2835
|
X as cameraFromPlane,
|
|
1150
2836
|
Y as cameraLookAt,
|
|
1151
|
-
|
|
2837
|
+
c4 as cast,
|
|
1152
2838
|
castShape,
|
|
1153
2839
|
chamfer,
|
|
1154
2840
|
chamferDistAngle as chamferDistAngleShape,
|
|
@@ -1156,43 +2842,46 @@ export {
|
|
|
1156
2842
|
checkInterference,
|
|
1157
2843
|
circle,
|
|
1158
2844
|
circularPattern,
|
|
1159
|
-
|
|
1160
|
-
|
|
2845
|
+
m7 as classifyPointOnFace,
|
|
2846
|
+
c5 as clearMeshCache,
|
|
1161
2847
|
clone,
|
|
1162
|
-
|
|
1163
|
-
|
|
2848
|
+
c as collect,
|
|
2849
|
+
d3 as collectShapes,
|
|
2850
|
+
k8 as colorFaces,
|
|
2851
|
+
l7 as colorShape,
|
|
1164
2852
|
f5 as complexExtrude,
|
|
1165
|
-
|
|
2853
|
+
w5 as composeTransforms,
|
|
1166
2854
|
compound,
|
|
1167
|
-
|
|
2855
|
+
c2 as compoundSketchExtrude,
|
|
1168
2856
|
d4 as compoundSketchFace,
|
|
1169
|
-
|
|
2857
|
+
e3 as compoundSketchLoft,
|
|
1170
2858
|
f7 as compoundSketchRevolve,
|
|
1171
|
-
|
|
2859
|
+
b2 as computationError,
|
|
2860
|
+
computeStraightSkeleton,
|
|
1172
2861
|
cone,
|
|
1173
|
-
|
|
2862
|
+
c6 as cornerFinder,
|
|
1174
2863
|
g6 as countNodes,
|
|
1175
|
-
|
|
1176
|
-
|
|
2864
|
+
h4 as createAssembly,
|
|
2865
|
+
i4 as createAssemblyNode,
|
|
1177
2866
|
createBlueprint,
|
|
1178
2867
|
Z as createCamera,
|
|
1179
|
-
|
|
2868
|
+
s2 as createCompound,
|
|
1180
2869
|
d8 as createDistanceQuery,
|
|
1181
|
-
|
|
1182
|
-
|
|
2870
|
+
p as createEdge,
|
|
2871
|
+
q as createFace,
|
|
1183
2872
|
a2 as createHandle,
|
|
1184
|
-
|
|
2873
|
+
j4 as createHistory,
|
|
1185
2874
|
b10 as createMeshCache,
|
|
1186
|
-
|
|
1187
|
-
|
|
2875
|
+
c3 as createNamedPlane,
|
|
2876
|
+
b3 as createOcHandle,
|
|
1188
2877
|
createOperationRegistry,
|
|
1189
2878
|
a7 as createPlane,
|
|
1190
|
-
|
|
1191
|
-
|
|
2879
|
+
k5 as createRegistry,
|
|
2880
|
+
y as createShell,
|
|
1192
2881
|
createSolid,
|
|
1193
2882
|
createTaskQueue,
|
|
1194
|
-
|
|
1195
|
-
|
|
2883
|
+
t3 as createVertex,
|
|
2884
|
+
createWire,
|
|
1196
2885
|
createWorkerClient,
|
|
1197
2886
|
createWorkerHandler,
|
|
1198
2887
|
curve2dBoundingBox,
|
|
@@ -1205,41 +2894,41 @@ export {
|
|
|
1205
2894
|
curve2dTangentAt,
|
|
1206
2895
|
curveEndPoint,
|
|
1207
2896
|
curveIsClosed,
|
|
1208
|
-
|
|
2897
|
+
k4 as curveIsPeriodic,
|
|
1209
2898
|
curveLength,
|
|
1210
|
-
|
|
2899
|
+
l4 as curvePeriod,
|
|
1211
2900
|
curvePointAt,
|
|
1212
2901
|
curveStartPoint,
|
|
1213
2902
|
curveTangentAt,
|
|
1214
2903
|
cut,
|
|
1215
|
-
|
|
2904
|
+
f6 as cut2D,
|
|
1216
2905
|
cutAll,
|
|
1217
|
-
|
|
2906
|
+
l5 as cutBlueprints,
|
|
1218
2907
|
cylinder,
|
|
1219
2908
|
dequeueTask,
|
|
1220
2909
|
describe,
|
|
1221
2910
|
g9 as deserializeDrawing,
|
|
1222
2911
|
fromBREP$1 as deserializeShape,
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
2912
|
+
d6 as downcast,
|
|
2913
|
+
h5 as draw,
|
|
2914
|
+
i5 as drawCircle,
|
|
2915
|
+
j5 as drawEllipse,
|
|
1227
2916
|
k7 as drawFaceOutline,
|
|
1228
|
-
|
|
2917
|
+
l6 as drawParametricFunction,
|
|
1229
2918
|
m5 as drawPointsInterpolation,
|
|
1230
2919
|
n5 as drawPolysides,
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
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,
|
|
1243
2932
|
drill,
|
|
1244
2933
|
edgeFinder,
|
|
1245
2934
|
e5 as edgesOfFace,
|
|
@@ -1252,78 +2941,90 @@ export {
|
|
|
1252
2941
|
exportDXF,
|
|
1253
2942
|
exportGlb,
|
|
1254
2943
|
exportGltf,
|
|
1255
|
-
|
|
2944
|
+
e6 as exportIGES,
|
|
1256
2945
|
exportOBJ,
|
|
1257
2946
|
d7 as exportSTEP,
|
|
1258
|
-
|
|
2947
|
+
f10 as exportSTL,
|
|
1259
2948
|
exportThreeMF,
|
|
1260
2949
|
extrude,
|
|
1261
2950
|
face,
|
|
1262
2951
|
faceCenter,
|
|
1263
2952
|
faceFinder,
|
|
1264
|
-
|
|
1265
|
-
|
|
2953
|
+
f9 as faceGeomType,
|
|
2954
|
+
q6 as faceOrientation,
|
|
1266
2955
|
f8 as facesOfEdge,
|
|
2956
|
+
p7 as fill,
|
|
1267
2957
|
filledFace,
|
|
1268
2958
|
fillet,
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
2959
|
+
f4 as findCurveType,
|
|
2960
|
+
m6 as findFacesByTag,
|
|
2961
|
+
n3 as findNode,
|
|
2962
|
+
o3 as findStep,
|
|
1272
2963
|
f2 as flatMap,
|
|
1273
|
-
|
|
1274
|
-
|
|
2964
|
+
r10 as flipFaceOrientation,
|
|
2965
|
+
m3 as flipOrientation,
|
|
2966
|
+
_ as fontMetrics,
|
|
1275
2967
|
fromBREP,
|
|
1276
2968
|
f as fromOcDir,
|
|
1277
2969
|
h as fromOcPnt,
|
|
1278
2970
|
i as fromOcVec,
|
|
1279
2971
|
fuse,
|
|
1280
|
-
|
|
2972
|
+
g7 as fuse2D,
|
|
1281
2973
|
fuseAll,
|
|
1282
|
-
|
|
1283
|
-
|
|
2974
|
+
n4 as fuseBlueprints,
|
|
2975
|
+
z2 as gcWithObject,
|
|
1284
2976
|
gcWithScope,
|
|
1285
|
-
|
|
2977
|
+
g5 as genericSweep,
|
|
1286
2978
|
getBounds,
|
|
1287
2979
|
getBounds2D,
|
|
1288
|
-
|
|
2980
|
+
b5 as getCurveType,
|
|
1289
2981
|
getEdges,
|
|
2982
|
+
n6 as getFaceColor,
|
|
1290
2983
|
g10 as getFaceOrigins,
|
|
2984
|
+
o6 as getFaceTags,
|
|
1291
2985
|
getFaces,
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
2986
|
+
$ as getFont,
|
|
2987
|
+
e4 as getHashCode,
|
|
2988
|
+
p2 as getHistoryShape,
|
|
1295
2989
|
getKernel,
|
|
1296
|
-
|
|
2990
|
+
g4 as getOrientation,
|
|
1297
2991
|
getOrientation2D,
|
|
2992
|
+
q5 as getShapeColor,
|
|
1298
2993
|
g2 as getShapeKind,
|
|
1299
2994
|
g8 as getSingleFace,
|
|
1300
2995
|
getSurfaceType,
|
|
2996
|
+
r9 as getTagMetadata,
|
|
1301
2997
|
getVertices,
|
|
1302
2998
|
getWires,
|
|
2999
|
+
guidedSweep,
|
|
1303
3000
|
heal,
|
|
1304
3001
|
d5 as healFace,
|
|
1305
3002
|
g11 as healSolid,
|
|
1306
|
-
|
|
3003
|
+
j7 as healWire,
|
|
1307
3004
|
helix,
|
|
3005
|
+
hull,
|
|
3006
|
+
importDXF,
|
|
1308
3007
|
importIGES,
|
|
3008
|
+
importOBJ,
|
|
1309
3009
|
importSTEP,
|
|
1310
3010
|
importSTL,
|
|
1311
3011
|
importSVG,
|
|
1312
3012
|
importSVGPathD,
|
|
3013
|
+
importThreeMF,
|
|
1313
3014
|
j as initFromOC,
|
|
1314
3015
|
innerWires,
|
|
1315
|
-
|
|
3016
|
+
n2 as interpolateCurve,
|
|
1316
3017
|
intersect,
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
3018
|
+
k6 as intersect2D,
|
|
3019
|
+
q3 as intersectBlueprints,
|
|
3020
|
+
ioError,
|
|
1320
3021
|
isChamferRadius,
|
|
1321
|
-
|
|
1322
|
-
|
|
3022
|
+
s5 as isCompSolid,
|
|
3023
|
+
i2 as isCompound,
|
|
1323
3024
|
isDisposeRequest,
|
|
1324
3025
|
isEdge,
|
|
1325
3026
|
isEmpty,
|
|
1326
|
-
|
|
3027
|
+
x3 as isEqualShape,
|
|
1327
3028
|
isErr,
|
|
1328
3029
|
isErrorResponse,
|
|
1329
3030
|
isFace,
|
|
@@ -1333,19 +3034,19 @@ export {
|
|
|
1333
3034
|
isNumber,
|
|
1334
3035
|
g as isOk,
|
|
1335
3036
|
isOperationRequest,
|
|
1336
|
-
|
|
3037
|
+
a0 as isProjectionPlane,
|
|
1337
3038
|
isQueueEmpty,
|
|
1338
|
-
|
|
3039
|
+
i6 as isSameShape,
|
|
1339
3040
|
f3 as isShape1D,
|
|
1340
3041
|
isShape3D,
|
|
1341
|
-
|
|
1342
|
-
|
|
3042
|
+
isShell,
|
|
3043
|
+
isSolid,
|
|
1343
3044
|
isSuccessResponse,
|
|
1344
3045
|
isValid,
|
|
1345
3046
|
l2 as isVertex,
|
|
1346
3047
|
isWire,
|
|
1347
|
-
|
|
1348
|
-
|
|
3048
|
+
y4 as iterEdges,
|
|
3049
|
+
z5 as iterFaces,
|
|
1349
3050
|
iterTopo,
|
|
1350
3051
|
A3 as iterVertices,
|
|
1351
3052
|
B5 as iterWires,
|
|
@@ -1353,79 +3054,86 @@ export {
|
|
|
1353
3054
|
kernelCallRaw,
|
|
1354
3055
|
line,
|
|
1355
3056
|
linearPattern,
|
|
1356
|
-
|
|
1357
|
-
|
|
3057
|
+
a1 as loadFont,
|
|
3058
|
+
r3 as localGC,
|
|
1358
3059
|
loft,
|
|
1359
3060
|
A2 as makeBaseBox,
|
|
1360
|
-
|
|
1361
|
-
|
|
3061
|
+
t4 as makePlane,
|
|
3062
|
+
a22 as makeProjectedEdges,
|
|
1362
3063
|
m as map,
|
|
1363
3064
|
h2 as mapErr,
|
|
1364
3065
|
j2 as match,
|
|
1365
3066
|
measureArea,
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
3067
|
+
e7 as measureCurvatureAt,
|
|
3068
|
+
f11 as measureCurvatureAtMid,
|
|
3069
|
+
g12 as measureDistance,
|
|
3070
|
+
h7 as measureLength,
|
|
3071
|
+
i7 as measureLinearProps,
|
|
1371
3072
|
measureSurfaceProps,
|
|
1372
3073
|
measureVolume,
|
|
1373
3074
|
measureVolumeProps,
|
|
1374
3075
|
mesh,
|
|
1375
3076
|
meshEdges,
|
|
3077
|
+
minkowski,
|
|
1376
3078
|
mirror,
|
|
1377
3079
|
mirror2D,
|
|
1378
3080
|
B4 as mirrorDrawing,
|
|
1379
3081
|
mirrorJoin,
|
|
1380
3082
|
q2 as modifyStep,
|
|
1381
3083
|
k2 as moduleInitError,
|
|
3084
|
+
multiSectionSweep,
|
|
1382
3085
|
normalAt,
|
|
1383
3086
|
occtError,
|
|
1384
3087
|
offset,
|
|
1385
3088
|
offsetFace,
|
|
1386
|
-
|
|
3089
|
+
o2 as offsetWire2D,
|
|
1387
3090
|
ok,
|
|
1388
|
-
|
|
3091
|
+
o4 as organiseBlueprints,
|
|
1389
3092
|
outerWire,
|
|
1390
3093
|
pendingCount,
|
|
1391
3094
|
z as pipeline,
|
|
1392
|
-
|
|
3095
|
+
p5 as pivotPlane,
|
|
1393
3096
|
pocket,
|
|
1394
|
-
|
|
3097
|
+
p6 as pointOnSurface,
|
|
1395
3098
|
polygon,
|
|
3099
|
+
polyhedron,
|
|
1396
3100
|
E2 as polysideInnerRadius,
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
3101
|
+
p3 as polysidesBlueprint,
|
|
3102
|
+
a32 as projectEdges,
|
|
3103
|
+
t10 as projectPointOnFace,
|
|
1400
3104
|
queryError,
|
|
1401
3105
|
rectangularPattern,
|
|
1402
3106
|
registerHandler,
|
|
1403
|
-
|
|
1404
|
-
|
|
3107
|
+
t5 as registerOperation,
|
|
3108
|
+
u as registerShape,
|
|
1405
3109
|
rejectAll,
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
3110
|
+
v3 as removeChild,
|
|
3111
|
+
x as replayFrom,
|
|
3112
|
+
y2 as replayHistory,
|
|
3113
|
+
C5 as resize,
|
|
1409
3114
|
resolve,
|
|
1410
3115
|
resolve3D,
|
|
1411
3116
|
r as resolveDirection,
|
|
1412
|
-
|
|
3117
|
+
r8 as resolvePlane,
|
|
1413
3118
|
reverseCurve,
|
|
1414
|
-
|
|
3119
|
+
r5 as revolution,
|
|
1415
3120
|
revolve,
|
|
3121
|
+
roof,
|
|
1416
3122
|
rotate,
|
|
1417
3123
|
rotate2D,
|
|
1418
3124
|
F2 as rotateDrawing,
|
|
1419
|
-
|
|
3125
|
+
r6 as roundedRectangleBlueprint,
|
|
1420
3126
|
scale,
|
|
1421
3127
|
scale2D,
|
|
1422
3128
|
G as scaleDrawing,
|
|
1423
3129
|
section,
|
|
1424
|
-
|
|
3130
|
+
sectionToFace,
|
|
3131
|
+
D4 as setShapeOrigin,
|
|
3132
|
+
t8 as setTagMetadata,
|
|
1425
3133
|
sewShells,
|
|
1426
3134
|
shape,
|
|
1427
|
-
|
|
1428
|
-
|
|
3135
|
+
v6 as shapeType,
|
|
3136
|
+
s4 as sharedEdges,
|
|
1429
3137
|
shell,
|
|
1430
3138
|
simplify,
|
|
1431
3139
|
sketch2DOnFace,
|
|
@@ -1443,28 +3151,33 @@ export {
|
|
|
1443
3151
|
R2 as sketchRevolve,
|
|
1444
3152
|
T as sketchRoundedRectangle,
|
|
1445
3153
|
U as sketchSweep,
|
|
1446
|
-
|
|
3154
|
+
a42 as sketchText,
|
|
1447
3155
|
V as sketchWires,
|
|
1448
3156
|
s as sketcherStateError,
|
|
1449
3157
|
slice,
|
|
1450
3158
|
solid,
|
|
3159
|
+
solveAssembly,
|
|
1451
3160
|
sphere,
|
|
1452
3161
|
split,
|
|
1453
|
-
|
|
1454
|
-
|
|
3162
|
+
z3 as stepCount,
|
|
3163
|
+
A as stepsFrom,
|
|
1455
3164
|
stretch2D,
|
|
1456
3165
|
subFace,
|
|
1457
|
-
|
|
3166
|
+
B2 as supportExtrude,
|
|
3167
|
+
surfaceFromGrid,
|
|
3168
|
+
surfaceFromImage,
|
|
1458
3169
|
sweep,
|
|
3170
|
+
u3 as tagFaces,
|
|
1459
3171
|
tangentArc,
|
|
1460
|
-
|
|
3172
|
+
a52 as textBlueprints,
|
|
3173
|
+
a62 as textMetrics,
|
|
1461
3174
|
thicken,
|
|
1462
3175
|
threePointArc,
|
|
1463
3176
|
toBREP,
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
3177
|
+
t9 as toBufferGeometryData,
|
|
3178
|
+
k9 as toGroupedBufferGeometryData,
|
|
3179
|
+
l8 as toLineGeometryData,
|
|
3180
|
+
b as toOcVec,
|
|
1468
3181
|
toSVGPathD,
|
|
1469
3182
|
t as toVec2,
|
|
1470
3183
|
toVec3,
|
|
@@ -1473,44 +3186,44 @@ export {
|
|
|
1473
3186
|
translate,
|
|
1474
3187
|
translate2D,
|
|
1475
3188
|
W as translateDrawing,
|
|
1476
|
-
|
|
3189
|
+
t7 as translatePlane,
|
|
1477
3190
|
t2 as tryCatch,
|
|
1478
3191
|
n as tryCatchAsync,
|
|
1479
|
-
|
|
3192
|
+
C2 as twistExtrude,
|
|
1480
3193
|
typeCastError,
|
|
1481
|
-
|
|
3194
|
+
D2 as undoLast,
|
|
1482
3195
|
unwrap,
|
|
1483
3196
|
r2 as unwrapErr,
|
|
1484
3197
|
v as unwrapOr,
|
|
1485
3198
|
w2 as unwrapOrElse,
|
|
1486
|
-
|
|
3199
|
+
E as updateNode,
|
|
1487
3200
|
u4 as uvBounds,
|
|
1488
|
-
|
|
3201
|
+
h6 as uvCoordinates,
|
|
1489
3202
|
validationError,
|
|
1490
|
-
|
|
3203
|
+
v2 as vecAdd,
|
|
1491
3204
|
a3 as vecAngle,
|
|
1492
|
-
|
|
3205
|
+
b4 as vecCross,
|
|
1493
3206
|
vecDistance,
|
|
1494
3207
|
d as vecDot,
|
|
1495
3208
|
e as vecEquals,
|
|
1496
3209
|
vecIsZero,
|
|
1497
3210
|
g3 as vecLength,
|
|
1498
3211
|
h3 as vecLengthSq,
|
|
1499
|
-
|
|
3212
|
+
i3 as vecNegate,
|
|
1500
3213
|
vecNormalize,
|
|
1501
|
-
|
|
3214
|
+
k3 as vecProjectToPlane,
|
|
1502
3215
|
l3 as vecRepr,
|
|
1503
3216
|
m2 as vecRotate,
|
|
1504
3217
|
vecScale,
|
|
1505
|
-
|
|
3218
|
+
o as vecSub,
|
|
1506
3219
|
vertex,
|
|
1507
3220
|
vertexFinder,
|
|
1508
3221
|
vertexPosition,
|
|
1509
|
-
|
|
1510
|
-
|
|
3222
|
+
v5 as verticesOfEdge,
|
|
3223
|
+
walkAssembly,
|
|
1511
3224
|
wire,
|
|
1512
3225
|
wireFinder,
|
|
1513
|
-
|
|
3226
|
+
w6 as wiresOfFace,
|
|
1514
3227
|
w as withOcDir,
|
|
1515
3228
|
k as withOcPnt,
|
|
1516
3229
|
l as withOcVec,
|