brepjs 18.18.0 → 18.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -14
- package/dist/2d.cjs +7 -7
- package/dist/2d.js +7 -7
- package/dist/{blueprint-Dz0LPfbm.cjs → blueprint-Bl0YQjkk.cjs} +7 -7
- package/dist/{blueprint-Dod3Pucj.js → blueprint-Cy5veXS3.js} +7 -7
- package/dist/{blueprintFns-BKCwR41V.js → blueprintFns-CSB51aXT.js} +3 -3
- package/dist/{blueprintFns-BFFIJd1K.cjs → blueprintFns-Dkccxo6d.cjs} +3 -3
- package/dist/{blueprintSketcher-BBWw_BeX.cjs → blueprintSketcher-Cr9A-R8I.cjs} +4 -4
- package/dist/{blueprintSketcher-mujcO3uV.js → blueprintSketcher-DeEogKbs.js} +4 -4
- package/dist/{boolean2D-Bx0_gvCS.cjs → boolean2D-BZ1UjpjX.cjs} +5 -5
- package/dist/{boolean2D-CdSpNYuw.js → boolean2D-lE2uy4Mm.js} +5 -5
- package/dist/{booleanFns-CipkzoSX.cjs → booleanFns-CD25YZGm.cjs} +6 -6
- package/dist/{booleanFns-D4r10eG8.js → booleanFns-CtvYfQZq.js} +6 -6
- package/dist/brepjs.cjs +1725 -34
- package/dist/brepjs.js +1737 -54
- package/dist/{cameraFns-BbgWV9ea.cjs → cameraFns-CR2inEBU.cjs} +3 -3
- package/dist/{cameraFns-DfqWQ17C.js → cameraFns-Dg1lQP0S.js} +3 -3
- package/dist/core/errors.d.ts +1 -0
- package/dist/core.cjs +3 -3
- package/dist/core.js +3 -3
- package/dist/{cornerFinder-ATn5SKjb.cjs → cornerFinder-CXN1IxPg.cjs} +1 -1
- package/dist/{cornerFinder-KEk4VpTe.js → cornerFinder-tfWhcA2M.js} +1 -1
- package/dist/csg/builders.d.ts +36 -0
- package/dist/csg/edit.d.ts +5 -0
- package/dist/csg/evaluate.d.ts +52 -0
- package/dist/csg/evaluators/booleans.d.ts +11 -0
- package/dist/csg/evaluators/compound.d.ts +8 -0
- package/dist/csg/evaluators/context.d.ts +9 -0
- package/dist/csg/evaluators/primitives.d.ts +15 -0
- package/dist/csg/evaluators/transforms.d.ts +10 -0
- package/dist/csg/expressions.d.ts +72 -0
- package/dist/csg/hash.d.ts +9 -0
- package/dist/csg/index.d.ts +15 -0
- package/dist/csg/optimize.d.ts +4 -0
- package/dist/csg/serialize.d.ts +9 -0
- package/dist/csg/types.d.ts +128 -0
- package/dist/{curveFns-DkpbzRtv.js → curveFns-BEF8t7XY.js} +2 -2
- package/dist/{curveFns-DhQVXMK0.cjs → curveFns-CcheHkr4.cjs} +2 -2
- package/dist/{drawFns-1JQUg7iu.js → drawFns-CEjshioX.js} +14 -14
- package/dist/{drawFns-N-BXk82r.cjs → drawFns-CuzUHFyD.cjs} +14 -14
- package/dist/{errors-0fYW_YnO.js → errors-8GZS3vy9.js} +1 -0
- package/dist/{errors-Dv6pfNct.cjs → errors-BiY8-q1s.cjs} +1 -0
- package/dist/{extrudeFns-DmNzWF1a.cjs → extrudeFns-BwU4ng1V.cjs} +2 -2
- package/dist/{extrudeFns-hUNicYgI.js → extrudeFns-gcWJSK9T.js} +2 -2
- package/dist/{faceFns-C9tfTZwq.js → faceFns-BNhFoEII.js} +3 -3
- package/dist/{faceFns-UQacl82e.cjs → faceFns-BbESdudy.cjs} +3 -3
- package/dist/{helpers-D4gm8z-T.cjs → helpers-BU3ANziG.cjs} +7 -7
- package/dist/{helpers-D3JzEtZl.js → helpers-D1J5VHbk.js} +7 -7
- package/dist/{historyFns-C3iimEbF.cjs → historyFns-DHOoBh6G.cjs} +5 -5
- package/dist/{historyFns-B4M2dl-F.js → historyFns-XZp1D_aA.js} +5 -5
- package/dist/{importFns-Cu1aMSAb.cjs → importFns-CsRJ9lbm.cjs} +3 -3
- package/dist/{importFns-CJd7ltsW.js → importFns-D1oB3yU8.js} +3 -3
- package/dist/index.d.ts +4 -1
- package/dist/io.cjs +2 -2
- package/dist/io.js +2 -2
- package/dist/kernel/index.d.ts +6 -0
- package/dist/{measureFns-DkNQXgnh.cjs → measureFns-BkoPw5JT.cjs} +4 -4
- package/dist/{measureFns-BTip3Aiz.js → measureFns-C3y_WX_E.js} +4 -4
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-BEGSUUSa.cjs → meshFns-CFMr9FBb.cjs} +3 -3
- package/dist/{meshFns-DWsgfwE8.js → meshFns-k0BdoBGR.js} +3 -3
- package/dist/ns/booleans.d.ts +1 -0
- package/dist/ns/csg.d.ts +4 -0
- package/dist/operations.cjs +2 -2
- package/dist/operations.js +2 -2
- package/dist/{planeOps-CH4ruLuj.cjs → planeOps-2EyPq0tU.cjs} +1 -1
- package/dist/{planeOps-4i2qEraD.js → planeOps-Bea3T3mc.js} +1 -1
- package/dist/{primitiveFns-BLIDnaB4.js → primitiveFns-BsO-feBX.js} +133 -8
- package/dist/{primitiveFns-BLyZbYzv.cjs → primitiveFns-CkMua35m.cjs} +144 -7
- package/dist/projection.cjs +1 -1
- package/dist/projection.js +1 -1
- package/dist/query.cjs +2 -2
- package/dist/query.js +2 -2
- package/dist/result.cjs +1 -1
- package/dist/result.js +1 -1
- package/dist/{shapeFns-CsFHf3W8.cjs → shapeFns-CHTLdb_n.cjs} +3 -3
- package/dist/{shapeFns-DaqT_8dv.js → shapeFns-x8vqq2fR.js} +3 -3
- package/dist/shapeRef.cjs +1 -1
- package/dist/shapeRef.js +1 -1
- package/dist/{shapeRefFns-WwBIiDUH.cjs → shapeRefFns-CDRLEUik.cjs} +4 -4
- package/dist/{shapeRefFns-BEsxgYOo.js → shapeRefFns-CE0yS0EB.js} +4 -4
- package/dist/{shapeTypes-BcAUN8Jp.cjs → shapeTypes-BpKhed-9.cjs} +15 -1
- package/dist/{shapeTypes-Dqjd8VMv.js → shapeTypes-DGtDTS9s.js} +10 -2
- package/dist/sketching.cjs +3 -3
- package/dist/sketching.js +3 -3
- package/dist/{solidBuilders-C8wxbX4w.cjs → solidBuilders-BlBaFSCS.cjs} +3 -3
- package/dist/{solidBuilders-CYtiaHtQ.js → solidBuilders-Cot05qzs.js} +3 -3
- package/dist/{surfaceBuilders-D60F6RHs.cjs → surfaceBuilders-frj7YRrD.cjs} +3 -3
- package/dist/{surfaceBuilders-CuChXov6.js → surfaceBuilders-zJyikeav.js} +3 -3
- package/dist/text.cjs +2 -2
- package/dist/text.js +2 -2
- package/dist/{textBlueprints-Cm_gPjjQ.js → textBlueprints-Bv6zhEyn.js} +9 -9
- package/dist/{textBlueprints-Cg2IOa7K.cjs → textBlueprints-CHh9SChA.cjs} +9 -9
- package/dist/{textMetrics-BExS67Zh.cjs → textMetrics-CKNdQX02.cjs} +2 -2
- package/dist/{textMetrics-Dbgikkim.js → textMetrics-vUJTTEFi.js} +2 -2
- package/dist/topology/booleanBatchFns.d.ts +55 -0
- package/dist/topology.cjs +9 -7
- package/dist/topology.d.ts +1 -0
- package/dist/topology.js +8 -8
- package/dist/{topologyQueryFns-C_rxyeER.cjs → topologyQueryFns-CHsPXNbI.cjs} +2 -2
- package/dist/{topologyQueryFns-DHbFP_6r.js → topologyQueryFns-CcWaCxeb.js} +2 -2
- package/dist/vectors.cjs +1 -1
- package/dist/vectors.js +1 -1
- package/package.json +1 -1
package/dist/brepjs.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as init, A as planarWire, B as createKernelHandle, C as isOrientedFace, D as manifoldShell, E as isValidSolid, F as as3D, H as isLive, I as is2D, J as withScopeResultAsync, K as withScope, L as is3D, M as getShapeKind, O as orientedFace, P as as2D, R as DisposalScope, S as isManifoldShell, T as isPlanarWire, V as getDisposalStats, W as resetDisposalStats, X as getActiveKernelId, Y as _usingCtx, Z as getKernel, _ as isSolid, a as createEdge, at as supportsProjection, b as closedWire, c as createSolid, ct as resetPerformanceStats, d as isCompound, et as initFromOC, f as isEdge, g as isShell, h as isShape3D, i as createCompound, it as supportsConstraintSketch, j as validSolid, k as planarFace, l as createVertex, m as isShape1D, n as castShape3D, nt as registerKernel, o as createFace, ot as BrepkitAdapter, p as isFace, q as withScopeResult, rt as withKernel, s as createShell, st as getPerformanceStats, t as castShape, tt as prewarm, u as createWire, v as isVertex, w as isPlanarFace, x as isClosedWire, y as isWire, z as createHandle } from "./shapeTypes-DGtDTS9s.js";
|
|
2
2
|
import { n as wasmIndex } from "./vec3-BRj3eI54.js";
|
|
3
3
|
import { t as OcctWasmAdapter } from "./occtWasmAdapter--TZGP9DX.js";
|
|
4
|
-
import { A as ok, B as unwrapOr, C as fromNullable, D as mapBoth, E as map, F as tapErr, H as zip, I as tryCatch, L as tryCatchAsync, M as orElse, N as pipeline, O as mapErr, P as tap, R as unwrap, S as flatten, T as isOk, V as unwrapOrElse, _ as all, a as moduleInitError, b as err, c as sketcherStateError, d as validationError, g as OK, h as bug, i as kernelError, j as or, k as match, l as typeCastError, m as BrepBugError, n as computationError, o as queryError, r as ioError, t as BrepErrorCode, u as unsupportedError, v as andThen, w as isErr, x as flatMap, y as collect, z as unwrapErr } from "./errors-
|
|
5
|
-
import { _ as kernelCall, a as getCachedSurfaceType, d as invalidateShapeCache, f as iterEdges, g as vertexPosition, h as iterWires, l as getVertices, m as iterVertices, n as getBounds, o as getEdges, p as iterFaces, s as getFaces, t as describe$1, u as getWires, v as kernelCallRaw, y as kernelCallScoped } from "./topologyQueryFns-
|
|
4
|
+
import { A as ok, B as unwrapOr, C as fromNullable, D as mapBoth, E as map, F as tapErr, H as zip, I as tryCatch, L as tryCatchAsync, M as orElse, N as pipeline, O as mapErr, P as tap, R as unwrap, S as flatten, T as isOk, V as unwrapOrElse, _ as all, a as moduleInitError, b as err, c as sketcherStateError, d as validationError, g as OK, h as bug, i as kernelError, j as or, k as match, l as typeCastError, m as BrepBugError, n as computationError, o as queryError, r as ioError, t as BrepErrorCode, u as unsupportedError, v as andThen, w as isErr, x as flatMap, y as collect, z as unwrapErr } from "./errors-8GZS3vy9.js";
|
|
5
|
+
import { _ as kernelCall, a as getCachedSurfaceType, d as invalidateShapeCache, f as iterEdges, g as vertexPosition, h as iterWires, l as getVertices, m as iterVertices, n as getBounds, o as getEdges, p as iterFaces, s as getFaces, t as describe$1, u as getWires, v as kernelCallRaw, y as kernelCallScoped } from "./topologyQueryFns-CcWaCxeb.js";
|
|
6
6
|
import { n as HASH_CODE_MAX, r as RAD2DEG, t as DEG2RAD } from "./constants-Ci5CA3aZ.js";
|
|
7
7
|
import { n as toVec2, r as toVec3, t as resolveDirection } from "./types-BIdk_GJY.js";
|
|
8
8
|
import { a as vecDot, c as vecLength, d as vecNormalize, f as vecProjectToPlane, g as vecSub, h as vecScale, i as vecDistance, l as vecLengthSq, m as vecRotate, n as vecAngle, o as vecEquals, p as vecRepr, r as vecCross, s as vecIsZero, t as vecAdd, u as vecNegate } from "./vecOps-DVROrqTV.js";
|
|
9
|
-
import { i as pivotPlane, n as createPlane, o as resolvePlane, r as makePlane, s as translatePlane, t as createNamedPlane } from "./planeOps-
|
|
10
|
-
import { _ as downcast, a as flipFaceOrientation, b as iterTopo, c as normalAt, d as projectPointOnFace, f as removeHolesFromFace, g as cast, h as asTopo, i as faceOrientation, l as outerWire, m as uvCoordinates, n as faceCenter, o as getSurfaceType, p as uvBounds, r as faceGeomType, s as innerWires, t as classifyPointOnFace, u as pointOnSurface, v as fromBREP, x as shapeType, y as isCompSolid } from "./faceFns-
|
|
11
|
-
import { C as findFacesByTag, D as tagFaces, E as setTagMetadata, O as getFaceOrigins, S as getShapeColor, T as getTagMetadata, a as isSameShape, b as colorShape, c as applyMatrix$1, d as resize, f as rotate$
|
|
12
|
-
import { a as curveLength, c as curveStartPoint, d as getCurveType, f as getOrientation, i as curveIsPeriodic, l as curveTangentAt, m as offsetWire2D, n as curveEndPoint, o as curvePeriod, p as interpolateCurve, r as curveIsClosed, s as curvePointAt, t as approximateCurve, u as flipOrientation } from "./curveFns-
|
|
13
|
-
import { a as meshEdges$1, c as createMeshCache, i as mesh$1, n as exportSTEP, o as meshMultiLOD, r as exportSTL, s as clearMeshCache, t as exportIGES } from "./meshFns-
|
|
9
|
+
import { i as pivotPlane, n as createPlane, o as resolvePlane, r as makePlane, s as translatePlane, t as createNamedPlane } from "./planeOps-Bea3T3mc.js";
|
|
10
|
+
import { _ as downcast, a as flipFaceOrientation, b as iterTopo, c as normalAt, d as projectPointOnFace, f as removeHolesFromFace, g as cast, h as asTopo, i as faceOrientation, l as outerWire, m as uvCoordinates, n as faceCenter, o as getSurfaceType, p as uvBounds, r as faceGeomType, s as innerWires, t as classifyPointOnFace, u as pointOnSurface, v as fromBREP, x as shapeType, y as isCompSolid } from "./faceFns-BNhFoEII.js";
|
|
11
|
+
import { C as findFacesByTag, D as tagFaces, E as setTagMetadata, O as getFaceOrigins, S as getShapeColor, T as getTagMetadata, a as isSameShape, b as colorShape, c as applyMatrix$1, d as resize, f as rotate$2, h as translate$2, i as isEqualShape, k as setShapeOrigin, l as composeTransforms, m as transformCopy$1, n as getHashCode, o as simplify$1, p as scale$2, r as isEmpty$2, s as toBREP$1, t as clone$1, u as mirror$2, w as getFaceTags, x as getFaceColor, y as colorFaces } from "./shapeFns-x8vqq2fR.js";
|
|
12
|
+
import { a as curveLength, c as curveStartPoint, d as getCurveType, f as getOrientation, i as curveIsPeriodic, l as curveTangentAt, m as offsetWire2D, n as curveEndPoint, o as curvePeriod, p as interpolateCurve, r as curveIsClosed, s as curvePointAt, t as approximateCurve, u as flipOrientation } from "./curveFns-BEF8t7XY.js";
|
|
13
|
+
import { a as meshEdges$1, c as createMeshCache, i as mesh$1, n as exportSTEP, o as meshMultiLOD, r as exportSTL, s as clearMeshCache, t as exportIGES } from "./meshFns-k0BdoBGR.js";
|
|
14
14
|
import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayAccess-C5IWcxs9.js";
|
|
15
|
-
import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, r as makeFace, s as assembleWire } from "./surfaceBuilders-
|
|
16
|
-
import { a as fuseAll, c as sectionToFace$1, i as fuse$
|
|
17
|
-
import { $ as
|
|
18
|
-
import { C as walkAssembly, D as exportAssemblySTEP, E as linearPattern, O as createAssembly, S as updateNode, _ as collectShapes, a as findStep, b as findNode, c as registerOperation, d as replayHistory, f as serializeHistory, g as addChild, h as undoLast, i as deserializeHistory, l as registerShape, m as stepsFrom, n as createHistory, o as getShape, p as stepCount, r as createRegistry, s as modifyStep, t as addStep, u as replayFrom, v as countNodes, w as circularPattern, x as removeChild, y as createAssemblyNode } from "./historyFns-
|
|
19
|
-
import { n as BaseSketcher2d, r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-
|
|
20
|
-
import { a as createTypedFinder, i as wireFinder, n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-
|
|
21
|
-
import { A as sketchEllipse, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-
|
|
22
|
-
import { r as makeCylinder } from "./solidBuilders-
|
|
23
|
-
import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, i as measureCurvatureAtMid, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, r as measureCurvatureAt, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns-
|
|
24
|
-
import { t as cornerFinder } from "./cornerFinder-
|
|
25
|
-
import { a as fuseBlueprints, c as roundedRectangleBlueprint, i as cutBlueprints, n as fuse2D, o as intersectBlueprints, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-
|
|
26
|
-
import { S as reverseCurve, _ as curve2dIsOnCurve, a as isInside2D, b as curve2dSplitAt, c as scale2D, d as stretch2D, f as toSVGPathD, g as curve2dFirstPoint, h as curve2dDistanceFrom, i as getOrientation2D, l as sketchOnFace2D, m as curve2dBoundingBox, n as createCompoundBlueprint, o as mirror2D, p as translate2D, r as getBounds2D, s as rotate2D, t as createBlueprint, u as sketchOnPlane2D, v as curve2dLastPoint, x as curve2dTangentAt, y as curve2dParameter } from "./blueprintFns-
|
|
27
|
-
import { a as importSVG, c as blueprintToDXF, d as exportGltf, f as exportOBJ, i as exportSTEPConfigured, l as exportDXF, n as importSTEP, o as importSVGPathD, r as importSTL, s as exportThreeMF, t as importIGES, u as exportGlb } from "./importFns-
|
|
28
|
-
import { a as guidedSweep, c as sweep, i as complexExtrude, l as twistExtrude, n as extrudeAll, o as multiSectionSweep, r as revolve$1, s as supportExtrude, t as extrude$1 } from "./extrudeFns-
|
|
29
|
-
import { a as Sketch, b as loftAll, c as compoundSketchLoft, d as sketchFace, f as sketchLoft, h as sketchWires, i as Sketches, l as compoundSketchRevolve, m as sketchSweep, n as getFont, o as compoundSketchExtrude, p as sketchRevolve, r as loadFont, s as compoundSketchFace, t as textBlueprints, u as sketchExtrude, v as CompoundSketch, y as loft$1 } from "./textBlueprints-
|
|
30
|
-
import { a as makeProjectedEdges, i as projectEdges, n as cameraLookAt, r as createCamera, s as isProjectionPlane, t as cameraFromPlane } from "./cameraFns-
|
|
31
|
-
import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-
|
|
32
|
-
import { a as updateRoles, i as resolveRef, n as captureHint, o as defaultScorer, r as createRef, t as assignRoles } from "./shapeRefFns-
|
|
15
|
+
import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, r as makeFace, s as assembleWire } from "./surfaceBuilders-zJyikeav.js";
|
|
16
|
+
import { a as fuseAll, c as sectionToFace$1, i as fuse$2, l as slice$1, n as cut$2, o as intersect$2, r as cutAll, s as section$1, t as booleanPipeline, u as split$1 } from "./booleanFns-CtvYfQZq.js";
|
|
17
|
+
import { $ as fuseAllBisect, A as fixShape, B as offset$1, C as threePointArc, D as wireLoop, E as wire, F as isValid$1, G as chamferWithEvolution, H as thicken$1, I as solidFromShell, J as fuseWithEvolution, K as cutWithEvolution, L as chamfer$1, M as healFace, N as healSolid, O as autoHeal, P as healWire, Q as cutAllBisect, R as draft$1, S as tangentArc, T as vertex, U as variableFillet, V as shell$1, W as positionOnCurve, X as shellWithEvolution, Y as intersectWithEvolution, Z as checkBoolean, _ as polygon, a as circle, at as sharedEdges, b as sphere, c as cylinder, ct as chamferDistAngle, d as ellipsoid, dt as toLODGeometryData, et as getNurbsCurveData, f as face, ft as toLineGeometryData, g as offsetFace, h as line, i as bsplineApprox, it as facesOfEdge, j as heal$1, k as fixSelfIntersection, l as ellipse, lt as toBufferGeometryData, m as helix, n as bezier, nt as adjacentFaces, o as compound, ot as verticesOfEdge, p as filledFace, q as filletWithEvolution, r as box, rt as edgesOfFace, s as cone, st as wiresOfFace, t as addHoles, tt as getNurbsSurfaceData, u as ellipseArc, ut as toGroupedBufferGeometryData, v as sewShells, w as torus, x as subFace, y as solid, z as fillet$1 } from "./primitiveFns-BsO-feBX.js";
|
|
18
|
+
import { C as walkAssembly, D as exportAssemblySTEP, E as linearPattern, O as createAssembly, S as updateNode, _ as collectShapes, a as findStep, b as findNode, c as registerOperation, d as replayHistory, f as serializeHistory, g as addChild, h as undoLast, i as deserializeHistory, l as registerShape, m as stepsFrom, n as createHistory, o as getShape, p as stepCount, r as createRegistry, s as modifyStep, t as addStep, u as replayFrom, v as countNodes, w as circularPattern, x as removeChild, y as createAssemblyNode } from "./historyFns-XZp1D_aA.js";
|
|
19
|
+
import { n as BaseSketcher2d, r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-DeEogKbs.js";
|
|
20
|
+
import { a as createTypedFinder, i as wireFinder, n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-D1J5VHbk.js";
|
|
21
|
+
import { A as sketchEllipse, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-CEjshioX.js";
|
|
22
|
+
import { r as makeCylinder } from "./solidBuilders-Cot05qzs.js";
|
|
23
|
+
import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, i as measureCurvatureAtMid, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, r as measureCurvatureAt, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns-C3y_WX_E.js";
|
|
24
|
+
import { t as cornerFinder } from "./cornerFinder-tfWhcA2M.js";
|
|
25
|
+
import { a as fuseBlueprints, c as roundedRectangleBlueprint, i as cutBlueprints, n as fuse2D, o as intersectBlueprints, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-lE2uy4Mm.js";
|
|
26
|
+
import { S as reverseCurve, _ as curve2dIsOnCurve, a as isInside2D, b as curve2dSplitAt, c as scale2D, d as stretch2D, f as toSVGPathD, g as curve2dFirstPoint, h as curve2dDistanceFrom, i as getOrientation2D, l as sketchOnFace2D, m as curve2dBoundingBox, n as createCompoundBlueprint, o as mirror2D, p as translate2D, r as getBounds2D, s as rotate2D, t as createBlueprint, u as sketchOnPlane2D, v as curve2dLastPoint, x as curve2dTangentAt, y as curve2dParameter } from "./blueprintFns-CSB51aXT.js";
|
|
27
|
+
import { a as importSVG, c as blueprintToDXF, d as exportGltf, f as exportOBJ, i as exportSTEPConfigured, l as exportDXF, n as importSTEP, o as importSVGPathD, r as importSTL, s as exportThreeMF, t as importIGES, u as exportGlb } from "./importFns-D1oB3yU8.js";
|
|
28
|
+
import { a as guidedSweep, c as sweep, i as complexExtrude, l as twistExtrude, n as extrudeAll, o as multiSectionSweep, r as revolve$1, s as supportExtrude, t as extrude$1 } from "./extrudeFns-gcWJSK9T.js";
|
|
29
|
+
import { a as Sketch, b as loftAll, c as compoundSketchLoft, d as sketchFace, f as sketchLoft, h as sketchWires, i as Sketches, l as compoundSketchRevolve, m as sketchSweep, n as getFont, o as compoundSketchExtrude, p as sketchRevolve, r as loadFont, s as compoundSketchFace, t as textBlueprints, u as sketchExtrude, v as CompoundSketch, y as loft$1 } from "./textBlueprints-Bv6zhEyn.js";
|
|
30
|
+
import { a as makeProjectedEdges, i as projectEdges, n as cameraLookAt, r as createCamera, s as isProjectionPlane, t as cameraFromPlane } from "./cameraFns-Dg1lQP0S.js";
|
|
31
|
+
import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-vUJTTEFi.js";
|
|
32
|
+
import { a as updateRoles, i as resolveRef, n as captureHint, o as defaultScorer, r as createRef, t as assignRoles } from "./shapeRefFns-CE0yS0EB.js";
|
|
33
33
|
import { a as createTaskQueue, c as isEmpty$1, d as isDisposeRequest, f as isErrorResponse, h as isSuccessResponse, i as createWorkerClient, l as pendingCount, m as isOperationRequest, n as createWorkerHandler, o as dequeueTask, p as isInitRequest, r as registerHandler, s as enqueueTask, t as createOperationRegistry, u as rejectAll } from "./workerHandler-DaulgMax.js";
|
|
34
34
|
//#region \0rolldown/runtime.js
|
|
35
35
|
var __defProp = Object.defineProperty;
|
|
@@ -1993,17 +1993,17 @@ function resolve3D(s) {
|
|
|
1993
1993
|
//#region src/topology/api.ts
|
|
1994
1994
|
/** Translate a shape by a vector. Returns a new shape. */
|
|
1995
1995
|
function translate(shape, v) {
|
|
1996
|
-
return translate$
|
|
1996
|
+
return translate$2(resolve(shape), v);
|
|
1997
1997
|
}
|
|
1998
1998
|
/** Rotate a shape around an axis. Angle is in degrees. Returns a new shape. */
|
|
1999
1999
|
function rotate(shape, angle, options) {
|
|
2000
2000
|
const pivotPoint = options?.at;
|
|
2001
|
-
return rotate$
|
|
2001
|
+
return rotate$2(resolve(shape), angle, pivotPoint, options?.axis);
|
|
2002
2002
|
}
|
|
2003
2003
|
/** Mirror a shape through a plane. Returns a new shape. */
|
|
2004
2004
|
function mirror(shape, options) {
|
|
2005
2005
|
const planeOrigin = options?.at;
|
|
2006
|
-
return mirror$
|
|
2006
|
+
return mirror$2(resolve(shape), options?.normal ?? [
|
|
2007
2007
|
1,
|
|
2008
2008
|
0,
|
|
2009
2009
|
0
|
|
@@ -2011,7 +2011,7 @@ function mirror(shape, options) {
|
|
|
2011
2011
|
}
|
|
2012
2012
|
/** Scale a shape uniformly. Returns a new shape. */
|
|
2013
2013
|
function scale(shape, factor, options) {
|
|
2014
|
-
return scale$
|
|
2014
|
+
return scale$2(resolve(shape), factor, options?.center);
|
|
2015
2015
|
}
|
|
2016
2016
|
/** Clone a shape (deep copy). */
|
|
2017
2017
|
function clone(shape) {
|
|
@@ -2036,21 +2036,21 @@ function transformCopy(shape, composed) {
|
|
|
2036
2036
|
}
|
|
2037
2037
|
/** Fuse two 3D shapes (boolean union). */
|
|
2038
2038
|
function fuse(a, b, options) {
|
|
2039
|
-
return fuse$
|
|
2039
|
+
return fuse$2(resolve(a), resolve(b), {
|
|
2040
2040
|
...options,
|
|
2041
2041
|
unsafe: true
|
|
2042
2042
|
});
|
|
2043
2043
|
}
|
|
2044
2044
|
/** Cut a tool from a base shape (boolean subtraction). */
|
|
2045
2045
|
function cut(base, tool, options) {
|
|
2046
|
-
return cut$
|
|
2046
|
+
return cut$2(resolve(base), resolve(tool), {
|
|
2047
2047
|
...options,
|
|
2048
2048
|
unsafe: true
|
|
2049
2049
|
});
|
|
2050
2050
|
}
|
|
2051
2051
|
/** Compute the intersection of two shapes (boolean common). */
|
|
2052
2052
|
function intersect(a, b, options) {
|
|
2053
|
-
return intersect$
|
|
2053
|
+
return intersect$2(resolve(a), resolve(b), {
|
|
2054
2054
|
...options,
|
|
2055
2055
|
unsafe: true
|
|
2056
2056
|
});
|
|
@@ -2353,7 +2353,7 @@ function drill(shape, options) {
|
|
|
2353
2353
|
pos[2] + dir[2] * tMin
|
|
2354
2354
|
], dir);
|
|
2355
2355
|
}
|
|
2356
|
-
return cut$
|
|
2356
|
+
return cut$2(s, tool, { unsafe: true });
|
|
2357
2357
|
}
|
|
2358
2358
|
/**
|
|
2359
2359
|
* Cut a pocket (2D profile extruded inward) into a shape.
|
|
@@ -2372,9 +2372,9 @@ function pocket(shape, options) {
|
|
|
2372
2372
|
const center = faceCenter(targetFace);
|
|
2373
2373
|
const faceResult = makeFace(toWire(profile));
|
|
2374
2374
|
if (isErr(faceResult)) return faceResult;
|
|
2375
|
-
const toolResult = extrude$1(translate$
|
|
2375
|
+
const toolResult = extrude$1(translate$2(faceResult.value, center), vecScale(vecNormalize(normal), -depth));
|
|
2376
2376
|
if (isErr(toolResult)) return toolResult;
|
|
2377
|
-
return cut$
|
|
2377
|
+
return cut$2(s, toolResult.value, { unsafe: true });
|
|
2378
2378
|
}
|
|
2379
2379
|
/**
|
|
2380
2380
|
* Add a boss (2D profile extruded outward) onto a shape.
|
|
@@ -2393,9 +2393,9 @@ function boss(shape, options) {
|
|
|
2393
2393
|
const center = faceCenter(targetFace);
|
|
2394
2394
|
const faceResult = makeFace(toWire(profile));
|
|
2395
2395
|
if (isErr(faceResult)) return faceResult;
|
|
2396
|
-
const toolResult = extrude$1(translate$
|
|
2396
|
+
const toolResult = extrude$1(translate$2(faceResult.value, center), vecScale(vecNormalize(normal), height));
|
|
2397
2397
|
if (isErr(toolResult)) return toolResult;
|
|
2398
|
-
return fuse$
|
|
2398
|
+
return fuse$2(s, toolResult.value, { unsafe: true });
|
|
2399
2399
|
}
|
|
2400
2400
|
/**
|
|
2401
2401
|
* Mirror a shape and fuse it with the original.
|
|
@@ -2411,7 +2411,7 @@ function mirrorJoin(shape, options) {
|
|
|
2411
2411
|
];
|
|
2412
2412
|
const planeOrigin = options?.at;
|
|
2413
2413
|
if (vecIsZero(normal)) return err(validationError("MIRROR_ZERO_NORMAL", "Mirror plane normal cannot be zero"));
|
|
2414
|
-
return fuse$
|
|
2414
|
+
return fuse$2(s, mirror$2(s, normal, planeOrigin), { unsafe: true });
|
|
2415
2415
|
}
|
|
2416
2416
|
/**
|
|
2417
2417
|
* Create a rectangular (2D grid) pattern of a shape.
|
|
@@ -2436,7 +2436,7 @@ function rectangularPattern(shape, options) {
|
|
|
2436
2436
|
xNorm[1] * xSpacing * xi + yNorm[1] * ySpacing * yi,
|
|
2437
2437
|
xNorm[2] * xSpacing * xi + yNorm[2] * ySpacing * yi
|
|
2438
2438
|
];
|
|
2439
|
-
copies.push(translate$
|
|
2439
|
+
copies.push(translate$2(s, offset));
|
|
2440
2440
|
}
|
|
2441
2441
|
return fuseAll(copies, { unsafe: true });
|
|
2442
2442
|
}
|
|
@@ -2882,12 +2882,12 @@ function makeInternalGearProfileWire(params) {
|
|
|
2882
2882
|
}
|
|
2883
2883
|
function makeProfileWire(params, isInternal) {
|
|
2884
2884
|
try {
|
|
2885
|
-
var _usingCtx$
|
|
2885
|
+
var _usingCtx$3 = _usingCtx();
|
|
2886
2886
|
const { teeth, moduleSize, pressureAngle, shift, clearance, flankThinning, samples = adaptiveSampleCount(moduleSize) } = params;
|
|
2887
2887
|
if (teeth < 4) return err(validationError("GEAR_TEETH_TOO_FEW", `gear needs ≥ 4 teeth, got ${teeth}`));
|
|
2888
2888
|
if (moduleSize <= 0) return err(validationError("GEAR_MODULE_NONPOSITIVE", `module must be > 0, got ${moduleSize}`));
|
|
2889
2889
|
const tm = gearGeometry(teeth, moduleSize, pressureAngle, shift, clearance, flankThinning, isInternal);
|
|
2890
|
-
const scope = _usingCtx$
|
|
2890
|
+
const scope = _usingCtx$3.u(new DisposalScope());
|
|
2891
2891
|
const allEdges = [];
|
|
2892
2892
|
for (let i = 0; i < teeth; i++) {
|
|
2893
2893
|
const periodEdges = buildToothPeriodEdges(tm, i, teeth, samples, scope);
|
|
@@ -2898,9 +2898,9 @@ function makeProfileWire(params, isInternal) {
|
|
|
2898
2898
|
if (isErr(wireResult)) return wireResult;
|
|
2899
2899
|
return ok(wireResult.value);
|
|
2900
2900
|
} catch (_) {
|
|
2901
|
-
_usingCtx$
|
|
2901
|
+
_usingCtx$3.e = _;
|
|
2902
2902
|
} finally {
|
|
2903
|
-
_usingCtx$
|
|
2903
|
+
_usingCtx$3.d();
|
|
2904
2904
|
}
|
|
2905
2905
|
}
|
|
2906
2906
|
//#endregion
|
|
@@ -3081,8 +3081,8 @@ function resolvePlanetaryParams(params) {
|
|
|
3081
3081
|
}
|
|
3082
3082
|
function makeOuterCircleWire(radius) {
|
|
3083
3083
|
try {
|
|
3084
|
-
var _usingCtx$
|
|
3085
|
-
const wireResult = assembleWire([_usingCtx$
|
|
3084
|
+
var _usingCtx$2 = _usingCtx();
|
|
3085
|
+
const wireResult = assembleWire([_usingCtx$2.u(new DisposalScope()).register(makeCircle(radius, [
|
|
3086
3086
|
0,
|
|
3087
3087
|
0,
|
|
3088
3088
|
0
|
|
@@ -3094,9 +3094,9 @@ function makeOuterCircleWire(radius) {
|
|
|
3094
3094
|
if (isErr(wireResult)) return wireResult;
|
|
3095
3095
|
return ok(wireResult.value);
|
|
3096
3096
|
} catch (_) {
|
|
3097
|
-
_usingCtx$
|
|
3097
|
+
_usingCtx$2.e = _;
|
|
3098
3098
|
} finally {
|
|
3099
|
-
_usingCtx$
|
|
3099
|
+
_usingCtx$2.d();
|
|
3100
3100
|
}
|
|
3101
3101
|
}
|
|
3102
3102
|
function finalizeExternalSolid(wire, thickness, bore, geom, diagnostics) {
|
|
@@ -3122,12 +3122,12 @@ function finalizeExternalSolid(wire, thickness, bore, geom, diagnostics) {
|
|
|
3122
3122
|
]);
|
|
3123
3123
|
if (isErr(boreRaw)) return boreRaw;
|
|
3124
3124
|
boreScope.register(boreRaw.value);
|
|
3125
|
-
const boreSolid = boreScope.register(translate$
|
|
3125
|
+
const boreSolid = boreScope.register(translate$2(boreRaw.value, [
|
|
3126
3126
|
0,
|
|
3127
3127
|
0,
|
|
3128
3128
|
-.5
|
|
3129
3129
|
]));
|
|
3130
|
-
const cutResult = cut$
|
|
3130
|
+
const cutResult = cut$2(solidResult.value, boreSolid);
|
|
3131
3131
|
if (isErr(cutResult)) return cutResult;
|
|
3132
3132
|
return ok(buildGearResult(cutResult.value, geom, diagnostics));
|
|
3133
3133
|
} catch (_) {
|
|
@@ -3167,14 +3167,14 @@ function placePlanets(planetProto, cfg) {
|
|
|
3167
3167
|
try {
|
|
3168
3168
|
for (let i = 0; i < cfg.numPlanets; i++) {
|
|
3169
3169
|
const orbital = i * 2 * Math.PI / cfg.numPlanets;
|
|
3170
|
-
const rotated = rotate$
|
|
3170
|
+
const rotated = rotate$2(planetProto, planetSelfRotationAngle(orbital, cfg.sunTeeth, cfg.planetTeeth) * 180 / Math.PI);
|
|
3171
3171
|
try {
|
|
3172
3172
|
const offset = [
|
|
3173
3173
|
cfg.centerDistance * Math.cos(orbital),
|
|
3174
3174
|
cfg.centerDistance * Math.sin(orbital),
|
|
3175
3175
|
0
|
|
3176
3176
|
];
|
|
3177
|
-
planets.push(translate$
|
|
3177
|
+
planets.push(translate$2(rotated, offset));
|
|
3178
3178
|
} finally {
|
|
3179
3179
|
rotated.delete();
|
|
3180
3180
|
}
|
|
@@ -3188,7 +3188,7 @@ function placePlanets(planetProto, cfg) {
|
|
|
3188
3188
|
function applyRingPhase(ring, zr) {
|
|
3189
3189
|
const phaseRad = evenToothPhaseOffset(zr);
|
|
3190
3190
|
if (phaseRad === 0) return ring;
|
|
3191
|
-
const rotated = rotate$
|
|
3191
|
+
const rotated = rotate$2(ring, phaseRad * 180 / Math.PI);
|
|
3192
3192
|
ring.delete();
|
|
3193
3193
|
return rotated;
|
|
3194
3194
|
}
|
|
@@ -3306,8 +3306,10 @@ var booleans_exports = /* @__PURE__ */ __exportAll({
|
|
|
3306
3306
|
convexHull: () => convexHull,
|
|
3307
3307
|
cut: () => cut,
|
|
3308
3308
|
cutAll: () => cutAll,
|
|
3309
|
+
cutAllBisect: () => cutAllBisect,
|
|
3309
3310
|
fuse: () => fuse,
|
|
3310
3311
|
fuseAll: () => fuseAll,
|
|
3312
|
+
fuseAllBisect: () => fuseAllBisect,
|
|
3311
3313
|
hull: () => hull,
|
|
3312
3314
|
intersect: () => intersect,
|
|
3313
3315
|
minkowski: () => minkowski,
|
|
@@ -3415,4 +3417,1685 @@ var patterns_exports = /* @__PURE__ */ __exportAll({
|
|
|
3415
3417
|
linearPattern: () => linearPattern
|
|
3416
3418
|
});
|
|
3417
3419
|
//#endregion
|
|
3418
|
-
|
|
3420
|
+
//#region src/csg/hash.ts
|
|
3421
|
+
var FNV_OFFSET = 14695981039346656037n;
|
|
3422
|
+
var FNV_PRIME = 1099511628211n;
|
|
3423
|
+
var MASK_64 = 18446744073709551615n;
|
|
3424
|
+
function fnvInit() {
|
|
3425
|
+
return FNV_OFFSET;
|
|
3426
|
+
}
|
|
3427
|
+
function fnvMixByte(h, byte) {
|
|
3428
|
+
return (h ^ BigInt(byte & 255)) * FNV_PRIME & MASK_64;
|
|
3429
|
+
}
|
|
3430
|
+
function fnvMixBytes(h, bytes) {
|
|
3431
|
+
let r = h;
|
|
3432
|
+
for (let i = 0; i < bytes.length; i++) r = fnvMixByte(r, bytes[i] ?? 0);
|
|
3433
|
+
return r;
|
|
3434
|
+
}
|
|
3435
|
+
var ENCODER = new TextEncoder();
|
|
3436
|
+
function fnvMixString(h, s) {
|
|
3437
|
+
return fnvMixBytes(h, ENCODER.encode(s));
|
|
3438
|
+
}
|
|
3439
|
+
var SCRATCH = /* @__PURE__ */ new ArrayBuffer(8);
|
|
3440
|
+
var SCRATCH_VIEW = new DataView(SCRATCH);
|
|
3441
|
+
var SCRATCH_BYTES = new Uint8Array(SCRATCH);
|
|
3442
|
+
function fnvMixNumber(h, n) {
|
|
3443
|
+
SCRATCH_VIEW.setFloat64(0, Object.is(n, -0) ? 0 : n);
|
|
3444
|
+
return fnvMixBytes(h, SCRATCH_BYTES);
|
|
3445
|
+
}
|
|
3446
|
+
function fnvMixHash(h, child) {
|
|
3447
|
+
let r = h;
|
|
3448
|
+
let v = child & MASK_64;
|
|
3449
|
+
for (let i = 0; i < 8; i++) {
|
|
3450
|
+
r = fnvMixByte(r, Number(v & 255n));
|
|
3451
|
+
v >>= 8n;
|
|
3452
|
+
}
|
|
3453
|
+
return r;
|
|
3454
|
+
}
|
|
3455
|
+
function fnvMixInt32(h, n) {
|
|
3456
|
+
let r = h;
|
|
3457
|
+
let v = n | 0;
|
|
3458
|
+
for (let i = 0; i < 4; i++) {
|
|
3459
|
+
r = fnvMixByte(r, v & 255);
|
|
3460
|
+
v >>>= 8;
|
|
3461
|
+
}
|
|
3462
|
+
return r;
|
|
3463
|
+
}
|
|
3464
|
+
function fnvMixBool(h, b) {
|
|
3465
|
+
return fnvMixByte(h, b ? 1 : 0);
|
|
3466
|
+
}
|
|
3467
|
+
function toHex(h) {
|
|
3468
|
+
return (h & MASK_64).toString(16).padStart(16, "0");
|
|
3469
|
+
}
|
|
3470
|
+
//#endregion
|
|
3471
|
+
//#region src/csg/expressions.ts
|
|
3472
|
+
var EMPTY_DEPS$1 = /* @__PURE__ */ new Set();
|
|
3473
|
+
function startHash$1(tag) {
|
|
3474
|
+
return fnvMixString(fnvInit(), tag);
|
|
3475
|
+
}
|
|
3476
|
+
function numLit(value) {
|
|
3477
|
+
return {
|
|
3478
|
+
kind: "NumLit",
|
|
3479
|
+
value,
|
|
3480
|
+
structuralHash: fnvMixNumber(startHash$1("NumLit"), value),
|
|
3481
|
+
freeParams: EMPTY_DEPS$1
|
|
3482
|
+
};
|
|
3483
|
+
}
|
|
3484
|
+
function vec3Lit(value) {
|
|
3485
|
+
let h = startHash$1("Vec3Lit");
|
|
3486
|
+
for (const n of value) h = fnvMixNumber(h, n);
|
|
3487
|
+
return {
|
|
3488
|
+
kind: "Vec3Lit",
|
|
3489
|
+
value,
|
|
3490
|
+
structuralHash: h,
|
|
3491
|
+
freeParams: EMPTY_DEPS$1
|
|
3492
|
+
};
|
|
3493
|
+
}
|
|
3494
|
+
function vec2Lit(value) {
|
|
3495
|
+
let h = startHash$1("Vec2Lit");
|
|
3496
|
+
for (const n of value) h = fnvMixNumber(h, n);
|
|
3497
|
+
return {
|
|
3498
|
+
kind: "Vec2Lit",
|
|
3499
|
+
value,
|
|
3500
|
+
structuralHash: h,
|
|
3501
|
+
freeParams: EMPTY_DEPS$1
|
|
3502
|
+
};
|
|
3503
|
+
}
|
|
3504
|
+
function param(name) {
|
|
3505
|
+
return {
|
|
3506
|
+
kind: "Param",
|
|
3507
|
+
name,
|
|
3508
|
+
structuralHash: fnvMixString(startHash$1("Param"), name),
|
|
3509
|
+
freeParams: new Set([name])
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
function binOp(op, a, b) {
|
|
3513
|
+
let h = fnvMixString(startHash$1("BinOp"), op);
|
|
3514
|
+
h = fnvMixHash(h, a.structuralHash);
|
|
3515
|
+
h = fnvMixHash(h, b.structuralHash);
|
|
3516
|
+
return {
|
|
3517
|
+
kind: "BinOp",
|
|
3518
|
+
op,
|
|
3519
|
+
a,
|
|
3520
|
+
b,
|
|
3521
|
+
structuralHash: h,
|
|
3522
|
+
freeParams: unionParams(a.freeParams, b.freeParams)
|
|
3523
|
+
};
|
|
3524
|
+
}
|
|
3525
|
+
function unaryOp(op, arg) {
|
|
3526
|
+
let h = fnvMixString(startHash$1("UnaryOp"), op);
|
|
3527
|
+
h = fnvMixHash(h, arg.structuralHash);
|
|
3528
|
+
return {
|
|
3529
|
+
kind: "UnaryOp",
|
|
3530
|
+
op,
|
|
3531
|
+
arg,
|
|
3532
|
+
structuralHash: h,
|
|
3533
|
+
freeParams: arg.freeParams
|
|
3534
|
+
};
|
|
3535
|
+
}
|
|
3536
|
+
function component(vec, index) {
|
|
3537
|
+
let h = fnvMixInt32(startHash$1("Component"), index);
|
|
3538
|
+
h = fnvMixHash(h, vec.structuralHash);
|
|
3539
|
+
return {
|
|
3540
|
+
kind: "Component",
|
|
3541
|
+
vec,
|
|
3542
|
+
index,
|
|
3543
|
+
structuralHash: h,
|
|
3544
|
+
freeParams: vec.freeParams
|
|
3545
|
+
};
|
|
3546
|
+
}
|
|
3547
|
+
function buildVec(dim, components) {
|
|
3548
|
+
let h = fnvMixInt32(startHash$1("BuildVec"), dim);
|
|
3549
|
+
const deps = /* @__PURE__ */ new Set();
|
|
3550
|
+
for (const c of components) {
|
|
3551
|
+
h = fnvMixHash(h, c.structuralHash);
|
|
3552
|
+
for (const p of c.freeParams) deps.add(p);
|
|
3553
|
+
}
|
|
3554
|
+
return {
|
|
3555
|
+
kind: "BuildVec",
|
|
3556
|
+
dim,
|
|
3557
|
+
components,
|
|
3558
|
+
structuralHash: h,
|
|
3559
|
+
freeParams: deps
|
|
3560
|
+
};
|
|
3561
|
+
}
|
|
3562
|
+
var add = (a, b) => binOp("+", a, b);
|
|
3563
|
+
var mul = (a, b) => binOp("*", a, b);
|
|
3564
|
+
function asScalarExpr(input) {
|
|
3565
|
+
return typeof input === "number" ? numLit(input) : input;
|
|
3566
|
+
}
|
|
3567
|
+
function asVecExpr(input, dim) {
|
|
3568
|
+
if (!Array.isArray(input)) return input;
|
|
3569
|
+
const arr = input;
|
|
3570
|
+
if (arr.every((v) => typeof v === "number")) return dim === 3 ? vec3Lit([
|
|
3571
|
+
arr[0],
|
|
3572
|
+
arr[1],
|
|
3573
|
+
arr[2]
|
|
3574
|
+
]) : vec2Lit([arr[0], arr[1]]);
|
|
3575
|
+
return buildVec(dim, arr.map(asScalarExpr));
|
|
3576
|
+
}
|
|
3577
|
+
function asVec3Expr(input) {
|
|
3578
|
+
return asVecExpr(input, 3);
|
|
3579
|
+
}
|
|
3580
|
+
function asVec2Expr(input) {
|
|
3581
|
+
return asVecExpr(input, 2);
|
|
3582
|
+
}
|
|
3583
|
+
function unionParams(a, b) {
|
|
3584
|
+
if (a.size === 0) return b;
|
|
3585
|
+
if (b.size === 0) return a;
|
|
3586
|
+
const out = new Set(a);
|
|
3587
|
+
for (const x of b) out.add(x);
|
|
3588
|
+
return out;
|
|
3589
|
+
}
|
|
3590
|
+
function isNumber$2(v) {
|
|
3591
|
+
return typeof v === "number";
|
|
3592
|
+
}
|
|
3593
|
+
function expectNumber(v, where) {
|
|
3594
|
+
if (isNumber$2(v)) return ok(v);
|
|
3595
|
+
return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `${where}: expected number, got ${Array.isArray(v) ? `vector(${v.length})` : typeof v}`));
|
|
3596
|
+
}
|
|
3597
|
+
function expectVecLen(v, len, where) {
|
|
3598
|
+
if (Array.isArray(v) && v.length === len) return ok(v);
|
|
3599
|
+
return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `${where}: expected Vec${len}, got ${isNumber$2(v) ? "number" : `vector(${v.length})`}`));
|
|
3600
|
+
}
|
|
3601
|
+
function evalExpr(expr, env) {
|
|
3602
|
+
switch (expr.kind) {
|
|
3603
|
+
case "NumLit": return ok(expr.value);
|
|
3604
|
+
case "Vec3Lit": return ok(expr.value);
|
|
3605
|
+
case "Vec2Lit": return ok(expr.value);
|
|
3606
|
+
case "Param": {
|
|
3607
|
+
const v = env[expr.name];
|
|
3608
|
+
if (v === void 0) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `unbound param: ${expr.name}`));
|
|
3609
|
+
return ok(v);
|
|
3610
|
+
}
|
|
3611
|
+
case "BinOp": return evalBinOp(expr, env);
|
|
3612
|
+
case "UnaryOp": return evalUnaryOp(expr, env);
|
|
3613
|
+
case "Component": return evalComponent(expr, env);
|
|
3614
|
+
case "BuildVec": return evalBuildVec(expr, env);
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3617
|
+
function evalBinOp(expr, env) {
|
|
3618
|
+
const ar = evalExpr(expr.a, env);
|
|
3619
|
+
if (!ar.ok) return ar;
|
|
3620
|
+
const br = evalExpr(expr.b, env);
|
|
3621
|
+
if (!br.ok) return br;
|
|
3622
|
+
const an = expectNumber(ar.value, `BinOp(${expr.op}).a`);
|
|
3623
|
+
if (!an.ok) return an;
|
|
3624
|
+
const bn = expectNumber(br.value, `BinOp(${expr.op}).b`);
|
|
3625
|
+
if (!bn.ok) return bn;
|
|
3626
|
+
switch (expr.op) {
|
|
3627
|
+
case "+": return ok(an.value + bn.value);
|
|
3628
|
+
case "-": return ok(an.value - bn.value);
|
|
3629
|
+
case "*": return ok(an.value * bn.value);
|
|
3630
|
+
case "/":
|
|
3631
|
+
if (bn.value === 0) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `BinOp(/): division by zero`));
|
|
3632
|
+
return ok(an.value / bn.value);
|
|
3633
|
+
}
|
|
3634
|
+
}
|
|
3635
|
+
function evalUnaryOp(expr, env) {
|
|
3636
|
+
const ar = evalExpr(expr.arg, env);
|
|
3637
|
+
if (!ar.ok) return ar;
|
|
3638
|
+
const an = expectNumber(ar.value, `UnaryOp(${expr.op})`);
|
|
3639
|
+
if (!an.ok) return an;
|
|
3640
|
+
const n = an.value;
|
|
3641
|
+
switch (expr.op) {
|
|
3642
|
+
case "neg": return ok(-n);
|
|
3643
|
+
case "sin": return ok(Math.sin(n));
|
|
3644
|
+
case "cos": return ok(Math.cos(n));
|
|
3645
|
+
case "sqrt": return ok(Math.sqrt(n));
|
|
3646
|
+
case "abs": return ok(Math.abs(n));
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
function evalComponent(expr, env) {
|
|
3650
|
+
const vr = evalExpr(expr.vec, env);
|
|
3651
|
+
if (!vr.ok) return vr;
|
|
3652
|
+
if (isNumber$2(vr.value)) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `Component: cannot index a scalar`));
|
|
3653
|
+
const v = vr.value;
|
|
3654
|
+
const c = v[expr.index];
|
|
3655
|
+
if (c === void 0) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `Component: index ${expr.index} out of range for Vec${v.length}`));
|
|
3656
|
+
return ok(c);
|
|
3657
|
+
}
|
|
3658
|
+
function evalBuildVec(expr, env) {
|
|
3659
|
+
if (expr.components.length !== expr.dim) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `BuildVec(${expr.dim}): expected ${expr.dim} components, got ${expr.components.length}`));
|
|
3660
|
+
const out = [];
|
|
3661
|
+
for (const c of expr.components) {
|
|
3662
|
+
const r = evalExpr(c, env);
|
|
3663
|
+
if (!r.ok) return r;
|
|
3664
|
+
const n = expectNumber(r.value, "BuildVec.component");
|
|
3665
|
+
if (!n.ok) return n;
|
|
3666
|
+
out.push(n.value);
|
|
3667
|
+
}
|
|
3668
|
+
return ok(expr.dim === 2 ? [out[0], out[1]] : [
|
|
3669
|
+
out[0],
|
|
3670
|
+
out[1],
|
|
3671
|
+
out[2]
|
|
3672
|
+
]);
|
|
3673
|
+
}
|
|
3674
|
+
function evalScalar(expr, env, where) {
|
|
3675
|
+
const r = evalExpr(expr, env);
|
|
3676
|
+
if (!r.ok) return r;
|
|
3677
|
+
return expectNumber(r.value, where);
|
|
3678
|
+
}
|
|
3679
|
+
function evalVec3(expr, env, where) {
|
|
3680
|
+
const r = evalExpr(expr, env);
|
|
3681
|
+
if (!r.ok) return r;
|
|
3682
|
+
const v = expectVecLen(r.value, 3, where);
|
|
3683
|
+
if (!v.ok) return v;
|
|
3684
|
+
const [a, b, c] = v.value;
|
|
3685
|
+
return ok([
|
|
3686
|
+
a,
|
|
3687
|
+
b,
|
|
3688
|
+
c
|
|
3689
|
+
]);
|
|
3690
|
+
}
|
|
3691
|
+
function projectEnv(env, deps) {
|
|
3692
|
+
if (deps.size === 0) return Object.freeze({});
|
|
3693
|
+
const out = {};
|
|
3694
|
+
for (const k of deps) {
|
|
3695
|
+
const v = env[k];
|
|
3696
|
+
if (v !== void 0) out[k] = v;
|
|
3697
|
+
}
|
|
3698
|
+
return Object.freeze(out);
|
|
3699
|
+
}
|
|
3700
|
+
//#endregion
|
|
3701
|
+
//#region src/csg/builders.ts
|
|
3702
|
+
var EMPTY_DEPS = /* @__PURE__ */ new Set();
|
|
3703
|
+
function startHash(tag) {
|
|
3704
|
+
return fnvMixString(fnvInit(), tag);
|
|
3705
|
+
}
|
|
3706
|
+
function mix(h, x) {
|
|
3707
|
+
return fnvMixHash(h, x.structuralHash);
|
|
3708
|
+
}
|
|
3709
|
+
function mixOptExpr(h, e) {
|
|
3710
|
+
if (e === void 0) return fnvMixBool(h, false);
|
|
3711
|
+
return mix(fnvMixBool(h, true), e);
|
|
3712
|
+
}
|
|
3713
|
+
function mixOptNumber(h, n) {
|
|
3714
|
+
if (n === void 0) return fnvMixBool(h, false);
|
|
3715
|
+
return fnvMixNumber(fnvMixBool(h, true), n);
|
|
3716
|
+
}
|
|
3717
|
+
function depsOf(...sources) {
|
|
3718
|
+
const acc = /* @__PURE__ */ new Set();
|
|
3719
|
+
for (const s of sources) {
|
|
3720
|
+
if (!s) continue;
|
|
3721
|
+
for (const p of s.freeParams) acc.add(p);
|
|
3722
|
+
}
|
|
3723
|
+
return acc.size === 0 ? EMPTY_DEPS : acc;
|
|
3724
|
+
}
|
|
3725
|
+
function box$1(x, y, z) {
|
|
3726
|
+
const xe = asScalarExpr(x);
|
|
3727
|
+
const ye = asScalarExpr(y);
|
|
3728
|
+
const ze = asScalarExpr(z);
|
|
3729
|
+
let h = startHash("Box");
|
|
3730
|
+
h = mix(mix(mix(h, xe), ye), ze);
|
|
3731
|
+
return {
|
|
3732
|
+
kind: "Box",
|
|
3733
|
+
x: xe,
|
|
3734
|
+
y: ye,
|
|
3735
|
+
z: ze,
|
|
3736
|
+
structuralHash: h,
|
|
3737
|
+
freeParams: depsOf(xe, ye, ze)
|
|
3738
|
+
};
|
|
3739
|
+
}
|
|
3740
|
+
function sphere$1(radius) {
|
|
3741
|
+
const re = asScalarExpr(radius);
|
|
3742
|
+
return {
|
|
3743
|
+
kind: "Sphere",
|
|
3744
|
+
radius: re,
|
|
3745
|
+
structuralHash: mix(startHash("Sphere"), re),
|
|
3746
|
+
freeParams: re.freeParams
|
|
3747
|
+
};
|
|
3748
|
+
}
|
|
3749
|
+
function cylinder$1(radius, height) {
|
|
3750
|
+
const re = asScalarExpr(radius);
|
|
3751
|
+
const he = asScalarExpr(height);
|
|
3752
|
+
return {
|
|
3753
|
+
kind: "Cylinder",
|
|
3754
|
+
radius: re,
|
|
3755
|
+
height: he,
|
|
3756
|
+
structuralHash: mix(mix(startHash("Cylinder"), re), he),
|
|
3757
|
+
freeParams: depsOf(re, he)
|
|
3758
|
+
};
|
|
3759
|
+
}
|
|
3760
|
+
function cone$1(radius1, radius2, height) {
|
|
3761
|
+
const r1 = asScalarExpr(radius1);
|
|
3762
|
+
const r2 = asScalarExpr(radius2);
|
|
3763
|
+
const he = asScalarExpr(height);
|
|
3764
|
+
let h = startHash("Cone");
|
|
3765
|
+
h = mix(mix(mix(h, r1), r2), he);
|
|
3766
|
+
return {
|
|
3767
|
+
kind: "Cone",
|
|
3768
|
+
radius1: r1,
|
|
3769
|
+
radius2: r2,
|
|
3770
|
+
height: he,
|
|
3771
|
+
structuralHash: h,
|
|
3772
|
+
freeParams: depsOf(r1, r2, he)
|
|
3773
|
+
};
|
|
3774
|
+
}
|
|
3775
|
+
function torus$1(majorRadius, minorRadius) {
|
|
3776
|
+
const ma = asScalarExpr(majorRadius);
|
|
3777
|
+
const mi = asScalarExpr(minorRadius);
|
|
3778
|
+
return {
|
|
3779
|
+
kind: "Torus",
|
|
3780
|
+
majorRadius: ma,
|
|
3781
|
+
minorRadius: mi,
|
|
3782
|
+
structuralHash: mix(mix(startHash("Torus"), ma), mi),
|
|
3783
|
+
freeParams: depsOf(ma, mi)
|
|
3784
|
+
};
|
|
3785
|
+
}
|
|
3786
|
+
function polygon$1(points) {
|
|
3787
|
+
const pts = points.map(asVec3Expr);
|
|
3788
|
+
let h = fnvMixInt32(startHash("Polygon"), pts.length);
|
|
3789
|
+
for (const p of pts) h = mix(h, p);
|
|
3790
|
+
return {
|
|
3791
|
+
kind: "Polygon",
|
|
3792
|
+
points: pts,
|
|
3793
|
+
structuralHash: h,
|
|
3794
|
+
freeParams: depsOf(...pts)
|
|
3795
|
+
};
|
|
3796
|
+
}
|
|
3797
|
+
function circle$1(radius) {
|
|
3798
|
+
const re = asScalarExpr(radius);
|
|
3799
|
+
return {
|
|
3800
|
+
kind: "Circle",
|
|
3801
|
+
radius: re,
|
|
3802
|
+
structuralHash: mix(startHash("Circle"), re),
|
|
3803
|
+
freeParams: re.freeParams
|
|
3804
|
+
};
|
|
3805
|
+
}
|
|
3806
|
+
function line$1(from, to) {
|
|
3807
|
+
const fe = asVec3Expr(from);
|
|
3808
|
+
const te = asVec3Expr(to);
|
|
3809
|
+
return {
|
|
3810
|
+
kind: "Line",
|
|
3811
|
+
from: fe,
|
|
3812
|
+
to: te,
|
|
3813
|
+
structuralHash: mix(mix(startHash("Line"), fe), te),
|
|
3814
|
+
freeParams: depsOf(fe, te)
|
|
3815
|
+
};
|
|
3816
|
+
}
|
|
3817
|
+
function vertex$1(point) {
|
|
3818
|
+
const pe = asVec3Expr(point);
|
|
3819
|
+
return {
|
|
3820
|
+
kind: "Vertex",
|
|
3821
|
+
point: pe,
|
|
3822
|
+
structuralHash: mix(startHash("Vertex"), pe),
|
|
3823
|
+
freeParams: pe.freeParams
|
|
3824
|
+
};
|
|
3825
|
+
}
|
|
3826
|
+
function emptyOf(output) {
|
|
3827
|
+
return {
|
|
3828
|
+
kind: "Empty",
|
|
3829
|
+
output,
|
|
3830
|
+
structuralHash: fnvMixString(startHash("Empty"), output),
|
|
3831
|
+
freeParams: EMPTY_DEPS
|
|
3832
|
+
};
|
|
3833
|
+
}
|
|
3834
|
+
function emptySolid() {
|
|
3835
|
+
return emptyOf("Solid");
|
|
3836
|
+
}
|
|
3837
|
+
function emptyFace() {
|
|
3838
|
+
return emptyOf("Face");
|
|
3839
|
+
}
|
|
3840
|
+
function emptyWire() {
|
|
3841
|
+
return emptyOf("Wire");
|
|
3842
|
+
}
|
|
3843
|
+
function binaryBoolHash(tag, a, b, tol) {
|
|
3844
|
+
return mixOptNumber(mix(mix(startHash(tag), a), b), tol);
|
|
3845
|
+
}
|
|
3846
|
+
function fuse$1(a, b, tolerance) {
|
|
3847
|
+
return {
|
|
3848
|
+
kind: "Fuse",
|
|
3849
|
+
a,
|
|
3850
|
+
b,
|
|
3851
|
+
tolerance,
|
|
3852
|
+
structuralHash: binaryBoolHash("Fuse", a, b, tolerance),
|
|
3853
|
+
freeParams: depsOf(a, b)
|
|
3854
|
+
};
|
|
3855
|
+
}
|
|
3856
|
+
function cut$1(a, b, tolerance) {
|
|
3857
|
+
return {
|
|
3858
|
+
kind: "Cut",
|
|
3859
|
+
a,
|
|
3860
|
+
b,
|
|
3861
|
+
tolerance,
|
|
3862
|
+
structuralHash: binaryBoolHash("Cut", a, b, tolerance),
|
|
3863
|
+
freeParams: depsOf(a, b)
|
|
3864
|
+
};
|
|
3865
|
+
}
|
|
3866
|
+
function intersect$1(a, b, tolerance) {
|
|
3867
|
+
return {
|
|
3868
|
+
kind: "Intersect",
|
|
3869
|
+
a,
|
|
3870
|
+
b,
|
|
3871
|
+
tolerance,
|
|
3872
|
+
structuralHash: binaryBoolHash("Intersect", a, b, tolerance),
|
|
3873
|
+
freeParams: depsOf(a, b)
|
|
3874
|
+
};
|
|
3875
|
+
}
|
|
3876
|
+
function fuseAll$1(shapes, tolerance) {
|
|
3877
|
+
let h = fnvMixInt32(startHash("FuseAll"), shapes.length);
|
|
3878
|
+
for (const s of shapes) h = mix(h, s);
|
|
3879
|
+
h = mixOptNumber(h, tolerance);
|
|
3880
|
+
return {
|
|
3881
|
+
kind: "FuseAll",
|
|
3882
|
+
shapes,
|
|
3883
|
+
tolerance,
|
|
3884
|
+
structuralHash: h,
|
|
3885
|
+
freeParams: depsOf(...shapes)
|
|
3886
|
+
};
|
|
3887
|
+
}
|
|
3888
|
+
function cutAll$1(base, tools, tolerance) {
|
|
3889
|
+
let h = mix(startHash("CutAll"), base);
|
|
3890
|
+
h = fnvMixInt32(h, tools.length);
|
|
3891
|
+
for (const t of tools) h = mix(h, t);
|
|
3892
|
+
h = mixOptNumber(h, tolerance);
|
|
3893
|
+
return {
|
|
3894
|
+
kind: "CutAll",
|
|
3895
|
+
base,
|
|
3896
|
+
tools,
|
|
3897
|
+
tolerance,
|
|
3898
|
+
structuralHash: h,
|
|
3899
|
+
freeParams: depsOf(base, ...tools)
|
|
3900
|
+
};
|
|
3901
|
+
}
|
|
3902
|
+
function optVec3$1(v) {
|
|
3903
|
+
return v !== void 0 ? asVec3Expr(v) : void 0;
|
|
3904
|
+
}
|
|
3905
|
+
function translate$1(target, vector) {
|
|
3906
|
+
const ve = asVec3Expr(vector);
|
|
3907
|
+
return {
|
|
3908
|
+
kind: "Translate",
|
|
3909
|
+
target,
|
|
3910
|
+
vector: ve,
|
|
3911
|
+
structuralHash: mix(mix(startHash("Translate"), target), ve),
|
|
3912
|
+
freeParams: depsOf(target, ve)
|
|
3913
|
+
};
|
|
3914
|
+
}
|
|
3915
|
+
function rotate$1(target, angle, options) {
|
|
3916
|
+
const ae = asScalarExpr(angle);
|
|
3917
|
+
const axisE = optVec3$1(options?.axis);
|
|
3918
|
+
const atE = optVec3$1(options?.at);
|
|
3919
|
+
let h = mix(mix(startHash("Rotate"), target), ae);
|
|
3920
|
+
h = mixOptExpr(h, axisE);
|
|
3921
|
+
h = mixOptExpr(h, atE);
|
|
3922
|
+
return {
|
|
3923
|
+
kind: "Rotate",
|
|
3924
|
+
target,
|
|
3925
|
+
angle: ae,
|
|
3926
|
+
axis: axisE,
|
|
3927
|
+
at: atE,
|
|
3928
|
+
structuralHash: h,
|
|
3929
|
+
freeParams: depsOf(target, ae, axisE, atE)
|
|
3930
|
+
};
|
|
3931
|
+
}
|
|
3932
|
+
function scale$1(target, factor, options) {
|
|
3933
|
+
const fe = asScalarExpr(factor);
|
|
3934
|
+
const cE = optVec3$1(options?.center);
|
|
3935
|
+
let h = mix(mix(startHash("Scale"), target), fe);
|
|
3936
|
+
h = mixOptExpr(h, cE);
|
|
3937
|
+
return {
|
|
3938
|
+
kind: "Scale",
|
|
3939
|
+
target,
|
|
3940
|
+
factor: fe,
|
|
3941
|
+
center: cE,
|
|
3942
|
+
structuralHash: h,
|
|
3943
|
+
freeParams: depsOf(target, fe, cE)
|
|
3944
|
+
};
|
|
3945
|
+
}
|
|
3946
|
+
function mirror$1(target, options) {
|
|
3947
|
+
const nE = optVec3$1(options?.normal);
|
|
3948
|
+
const atE = optVec3$1(options?.at);
|
|
3949
|
+
let h = mix(startHash("Mirror"), target);
|
|
3950
|
+
h = mixOptExpr(h, nE);
|
|
3951
|
+
h = mixOptExpr(h, atE);
|
|
3952
|
+
return {
|
|
3953
|
+
kind: "Mirror",
|
|
3954
|
+
target,
|
|
3955
|
+
normal: nE,
|
|
3956
|
+
at: atE,
|
|
3957
|
+
structuralHash: h,
|
|
3958
|
+
freeParams: depsOf(target, nE, atE)
|
|
3959
|
+
};
|
|
3960
|
+
}
|
|
3961
|
+
function compound$1(children) {
|
|
3962
|
+
let h = fnvMixInt32(startHash("Compound"), children.length);
|
|
3963
|
+
for (const c of children) h = mix(h, c);
|
|
3964
|
+
return {
|
|
3965
|
+
kind: "Compound",
|
|
3966
|
+
children,
|
|
3967
|
+
structuralHash: h,
|
|
3968
|
+
freeParams: depsOf(...children)
|
|
3969
|
+
};
|
|
3970
|
+
}
|
|
3971
|
+
//#endregion
|
|
3972
|
+
//#region src/csg/types.ts
|
|
3973
|
+
function outputKindOf(node) {
|
|
3974
|
+
switch (node.kind) {
|
|
3975
|
+
case "Box":
|
|
3976
|
+
case "Sphere":
|
|
3977
|
+
case "Cylinder":
|
|
3978
|
+
case "Cone":
|
|
3979
|
+
case "Torus": return "Solid";
|
|
3980
|
+
case "Polygon": return "Face";
|
|
3981
|
+
case "Circle":
|
|
3982
|
+
case "Line": return "Edge";
|
|
3983
|
+
case "Vertex": return "Vertex";
|
|
3984
|
+
case "Empty": return node.output;
|
|
3985
|
+
case "Fuse":
|
|
3986
|
+
case "Cut":
|
|
3987
|
+
case "Intersect": return outputKindOf(node.a);
|
|
3988
|
+
case "FuseAll": return node.shapes[0] ? outputKindOf(node.shapes[0]) : "Solid";
|
|
3989
|
+
case "CutAll": return outputKindOf(node.base);
|
|
3990
|
+
case "Translate":
|
|
3991
|
+
case "Rotate":
|
|
3992
|
+
case "Scale":
|
|
3993
|
+
case "Mirror": return outputKindOf(node.target);
|
|
3994
|
+
case "Compound": return "Compound";
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
//#endregion
|
|
3998
|
+
//#region src/csg/evaluators/primitives.ts
|
|
3999
|
+
function evalBox(node, ctx) {
|
|
4000
|
+
const x = evalScalar(node.x, ctx.env, "Box.x");
|
|
4001
|
+
if (!x.ok) return x;
|
|
4002
|
+
const y = evalScalar(node.y, ctx.env, "Box.y");
|
|
4003
|
+
if (!y.ok) return y;
|
|
4004
|
+
const z = evalScalar(node.z, ctx.env, "Box.z");
|
|
4005
|
+
if (!z.ok) return z;
|
|
4006
|
+
return ok(box(x.value, y.value, z.value));
|
|
4007
|
+
}
|
|
4008
|
+
function evalSphere(node, ctx) {
|
|
4009
|
+
const r = evalScalar(node.radius, ctx.env, "Sphere.radius");
|
|
4010
|
+
if (!r.ok) return r;
|
|
4011
|
+
return ok(sphere(r.value));
|
|
4012
|
+
}
|
|
4013
|
+
function evalCylinder(node, ctx) {
|
|
4014
|
+
const r = evalScalar(node.radius, ctx.env, "Cylinder.radius");
|
|
4015
|
+
if (!r.ok) return r;
|
|
4016
|
+
const h = evalScalar(node.height, ctx.env, "Cylinder.height");
|
|
4017
|
+
if (!h.ok) return h;
|
|
4018
|
+
return ok(cylinder(r.value, h.value));
|
|
4019
|
+
}
|
|
4020
|
+
function evalCone(node, ctx) {
|
|
4021
|
+
const r1 = evalScalar(node.radius1, ctx.env, "Cone.radius1");
|
|
4022
|
+
if (!r1.ok) return r1;
|
|
4023
|
+
const r2 = evalScalar(node.radius2, ctx.env, "Cone.radius2");
|
|
4024
|
+
if (!r2.ok) return r2;
|
|
4025
|
+
const h = evalScalar(node.height, ctx.env, "Cone.height");
|
|
4026
|
+
if (!h.ok) return h;
|
|
4027
|
+
return ok(cone(r1.value, r2.value, h.value));
|
|
4028
|
+
}
|
|
4029
|
+
function evalTorus(node, ctx) {
|
|
4030
|
+
const ma = evalScalar(node.majorRadius, ctx.env, "Torus.majorRadius");
|
|
4031
|
+
if (!ma.ok) return ma;
|
|
4032
|
+
const mi = evalScalar(node.minorRadius, ctx.env, "Torus.minorRadius");
|
|
4033
|
+
if (!mi.ok) return mi;
|
|
4034
|
+
return ok(torus(ma.value, mi.value));
|
|
4035
|
+
}
|
|
4036
|
+
function evalPolygon(node, ctx) {
|
|
4037
|
+
const pts = [];
|
|
4038
|
+
for (const p of node.points) {
|
|
4039
|
+
const r = evalVec3(p, ctx.env, "Polygon.point");
|
|
4040
|
+
if (!r.ok) return r;
|
|
4041
|
+
pts.push(r.value);
|
|
4042
|
+
}
|
|
4043
|
+
return polygon(pts);
|
|
4044
|
+
}
|
|
4045
|
+
function evalCircle(node, ctx) {
|
|
4046
|
+
const r = evalScalar(node.radius, ctx.env, "Circle.radius");
|
|
4047
|
+
if (!r.ok) return r;
|
|
4048
|
+
return ok(circle(r.value));
|
|
4049
|
+
}
|
|
4050
|
+
function evalLine(node, ctx) {
|
|
4051
|
+
const f = evalVec3(node.from, ctx.env, "Line.from");
|
|
4052
|
+
if (!f.ok) return f;
|
|
4053
|
+
const t = evalVec3(node.to, ctx.env, "Line.to");
|
|
4054
|
+
if (!t.ok) return t;
|
|
4055
|
+
return ok(line(f.value, t.value));
|
|
4056
|
+
}
|
|
4057
|
+
function evalVertex(node, ctx) {
|
|
4058
|
+
const p = evalVec3(node.point, ctx.env, "Vertex.point");
|
|
4059
|
+
if (!p.ok) return p;
|
|
4060
|
+
return ok(vertex(p.value));
|
|
4061
|
+
}
|
|
4062
|
+
//#endregion
|
|
4063
|
+
//#region src/csg/evaluators/booleans.ts
|
|
4064
|
+
/**
|
|
4065
|
+
* Evaluators for CSG boolean nodes.
|
|
4066
|
+
*
|
|
4067
|
+
* Identity short-circuits are correctness invariants, not optimisations:
|
|
4068
|
+
* Fuse with an Empty operand: short-circuits to the other operand
|
|
4069
|
+
* Cut with an Empty tool: short-circuits to the base
|
|
4070
|
+
* Intersect with any Empty: errors (no empty-solid representation)
|
|
4071
|
+
*
|
|
4072
|
+
* The optimizer pass handles broader rewrites; these inline checks just
|
|
4073
|
+
* keep the evaluator from feeding null operands to the kernel.
|
|
4074
|
+
*/
|
|
4075
|
+
function emptyResult$1(kind) {
|
|
4076
|
+
return err(computationError(BrepErrorCode.NULL_SHAPE_INPUT, `${kind}: empty result has no kernel representation`));
|
|
4077
|
+
}
|
|
4078
|
+
function resolveOperand(ctx, node, where) {
|
|
4079
|
+
const r = ctx.evalNode(node);
|
|
4080
|
+
if (!r.ok) return r;
|
|
4081
|
+
if (!isShape3D(r.value)) return err(typeCastError(BrepErrorCode.CSG_NOT_3D, `${where}: operand did not produce a 3D shape`));
|
|
4082
|
+
return ok(r.value);
|
|
4083
|
+
}
|
|
4084
|
+
function boolOptions(node, ctx) {
|
|
4085
|
+
return {
|
|
4086
|
+
unsafe: true,
|
|
4087
|
+
fuzzyValue: node.tolerance ?? ctx.tolerance
|
|
4088
|
+
};
|
|
4089
|
+
}
|
|
4090
|
+
function evalFuse(node, ctx) {
|
|
4091
|
+
if (node.a.kind === "Empty") return ctx.evalNode(node.b);
|
|
4092
|
+
if (node.b.kind === "Empty") return ctx.evalNode(node.a);
|
|
4093
|
+
const a = resolveOperand(ctx, node.a, "Fuse.a");
|
|
4094
|
+
if (!a.ok) return a;
|
|
4095
|
+
const b = resolveOperand(ctx, node.b, "Fuse.b");
|
|
4096
|
+
if (!b.ok) return b;
|
|
4097
|
+
return fuse$2(a.value, b.value, boolOptions(node, ctx));
|
|
4098
|
+
}
|
|
4099
|
+
function evalCut(node, ctx) {
|
|
4100
|
+
if (node.a.kind === "Empty") return emptyResult$1("Cut");
|
|
4101
|
+
if (node.b.kind === "Empty") return ctx.evalNode(node.a);
|
|
4102
|
+
const a = resolveOperand(ctx, node.a, "Cut.a");
|
|
4103
|
+
if (!a.ok) return a;
|
|
4104
|
+
const b = resolveOperand(ctx, node.b, "Cut.b");
|
|
4105
|
+
if (!b.ok) return b;
|
|
4106
|
+
return cut$2(a.value, b.value, boolOptions(node, ctx));
|
|
4107
|
+
}
|
|
4108
|
+
function evalIntersect(node, ctx) {
|
|
4109
|
+
if (node.a.kind === "Empty" || node.b.kind === "Empty") return emptyResult$1("Intersect");
|
|
4110
|
+
const a = resolveOperand(ctx, node.a, "Intersect.a");
|
|
4111
|
+
if (!a.ok) return a;
|
|
4112
|
+
const b = resolveOperand(ctx, node.b, "Intersect.b");
|
|
4113
|
+
if (!b.ok) return b;
|
|
4114
|
+
return intersect$2(a.value, b.value, boolOptions(node, ctx));
|
|
4115
|
+
}
|
|
4116
|
+
function resolveAll(ctx, nodes, where) {
|
|
4117
|
+
const out = [];
|
|
4118
|
+
for (const n of nodes) {
|
|
4119
|
+
const r = resolveOperand(ctx, n, where);
|
|
4120
|
+
if (!r.ok) return r;
|
|
4121
|
+
out.push(r.value);
|
|
4122
|
+
}
|
|
4123
|
+
return ok(out);
|
|
4124
|
+
}
|
|
4125
|
+
function evalFuseAll(node, ctx) {
|
|
4126
|
+
const non = node.shapes.filter((s) => s.kind !== "Empty");
|
|
4127
|
+
if (non.length === 0) return emptyResult$1("FuseAll");
|
|
4128
|
+
if (non.length === 1 && non[0]) return ctx.evalNode(non[0]);
|
|
4129
|
+
const resolved = resolveAll(ctx, non, "FuseAll.operand");
|
|
4130
|
+
if (!resolved.ok) return resolved;
|
|
4131
|
+
return fuseAll(resolved.value, boolOptions(node, ctx));
|
|
4132
|
+
}
|
|
4133
|
+
function evalCutAll(node, ctx) {
|
|
4134
|
+
if (node.base.kind === "Empty") return emptyResult$1("CutAll");
|
|
4135
|
+
const tools = node.tools.filter((s) => s.kind !== "Empty");
|
|
4136
|
+
if (tools.length === 0) return ctx.evalNode(node.base);
|
|
4137
|
+
const base = resolveOperand(ctx, node.base, "CutAll.base");
|
|
4138
|
+
if (!base.ok) return base;
|
|
4139
|
+
const resolved = resolveAll(ctx, tools, "CutAll.tool");
|
|
4140
|
+
if (!resolved.ok) return resolved;
|
|
4141
|
+
return cutAll(base.value, resolved.value, boolOptions(node, ctx));
|
|
4142
|
+
}
|
|
4143
|
+
//#endregion
|
|
4144
|
+
//#region src/csg/evaluators/transforms.ts
|
|
4145
|
+
function emptyResult(kind) {
|
|
4146
|
+
return err(computationError(BrepErrorCode.NULL_SHAPE_INPUT, `${kind}: cannot transform an Empty node`));
|
|
4147
|
+
}
|
|
4148
|
+
function optVec3(expr, env, where, fallback) {
|
|
4149
|
+
return expr ? evalVec3(expr, env, where) : ok(fallback);
|
|
4150
|
+
}
|
|
4151
|
+
function evalTranslate(node, ctx) {
|
|
4152
|
+
if (node.target.kind === "Empty") return emptyResult("Translate");
|
|
4153
|
+
const v = evalVec3(node.vector, ctx.env, "Translate.vector");
|
|
4154
|
+
if (!v.ok) return v;
|
|
4155
|
+
const r = ctx.evalNode(node.target);
|
|
4156
|
+
if (!r.ok) return r;
|
|
4157
|
+
return ok(translate$2(r.value, v.value));
|
|
4158
|
+
}
|
|
4159
|
+
function evalRotate(node, ctx) {
|
|
4160
|
+
if (node.target.kind === "Empty") return emptyResult("Rotate");
|
|
4161
|
+
const a = evalScalar(node.angle, ctx.env, "Rotate.angle");
|
|
4162
|
+
if (!a.ok) return a;
|
|
4163
|
+
const axis = optVec3(node.axis, ctx.env, "Rotate.axis", [
|
|
4164
|
+
0,
|
|
4165
|
+
0,
|
|
4166
|
+
1
|
|
4167
|
+
]);
|
|
4168
|
+
if (!axis.ok) return axis;
|
|
4169
|
+
const at = optVec3(node.at, ctx.env, "Rotate.at", [
|
|
4170
|
+
0,
|
|
4171
|
+
0,
|
|
4172
|
+
0
|
|
4173
|
+
]);
|
|
4174
|
+
if (!at.ok) return at;
|
|
4175
|
+
const r = ctx.evalNode(node.target);
|
|
4176
|
+
if (!r.ok) return r;
|
|
4177
|
+
return ok(rotate$2(r.value, a.value, at.value, axis.value));
|
|
4178
|
+
}
|
|
4179
|
+
function evalScale(node, ctx) {
|
|
4180
|
+
if (node.target.kind === "Empty") return emptyResult("Scale");
|
|
4181
|
+
const f = evalScalar(node.factor, ctx.env, "Scale.factor");
|
|
4182
|
+
if (!f.ok) return f;
|
|
4183
|
+
const center = optVec3(node.center, ctx.env, "Scale.center", [
|
|
4184
|
+
0,
|
|
4185
|
+
0,
|
|
4186
|
+
0
|
|
4187
|
+
]);
|
|
4188
|
+
if (!center.ok) return center;
|
|
4189
|
+
const r = ctx.evalNode(node.target);
|
|
4190
|
+
if (!r.ok) return r;
|
|
4191
|
+
return ok(scale$2(r.value, f.value, center.value));
|
|
4192
|
+
}
|
|
4193
|
+
function evalMirror(node, ctx) {
|
|
4194
|
+
if (node.target.kind === "Empty") return emptyResult("Mirror");
|
|
4195
|
+
const normal = optVec3(node.normal, ctx.env, "Mirror.normal", [
|
|
4196
|
+
1,
|
|
4197
|
+
0,
|
|
4198
|
+
0
|
|
4199
|
+
]);
|
|
4200
|
+
if (!normal.ok) return normal;
|
|
4201
|
+
const at = optVec3(node.at, ctx.env, "Mirror.at", [
|
|
4202
|
+
0,
|
|
4203
|
+
0,
|
|
4204
|
+
0
|
|
4205
|
+
]);
|
|
4206
|
+
if (!at.ok) return at;
|
|
4207
|
+
const r = ctx.evalNode(node.target);
|
|
4208
|
+
if (!r.ok) return r;
|
|
4209
|
+
return ok(mirror$2(r.value, normal.value, at.value));
|
|
4210
|
+
}
|
|
4211
|
+
//#endregion
|
|
4212
|
+
//#region src/csg/evaluators/compound.ts
|
|
4213
|
+
function evalCompound(node, ctx) {
|
|
4214
|
+
const non = node.children.filter((c) => c.kind !== "Empty");
|
|
4215
|
+
if (non.length === 0) return err(computationError(BrepErrorCode.NULL_SHAPE_INPUT, "Compound: cannot materialize a compound with zero non-empty children"));
|
|
4216
|
+
const shapes = [];
|
|
4217
|
+
for (const c of non) {
|
|
4218
|
+
const r = ctx.evalNode(c);
|
|
4219
|
+
if (!r.ok) return r;
|
|
4220
|
+
shapes.push(r.value);
|
|
4221
|
+
}
|
|
4222
|
+
return ok(compound(shapes));
|
|
4223
|
+
}
|
|
4224
|
+
function evalEmpty() {
|
|
4225
|
+
return err(computationError(BrepErrorCode.NULL_SHAPE_INPUT, "Empty: cannot materialize an Empty node directly — only valid as boolean/transform operand"));
|
|
4226
|
+
}
|
|
4227
|
+
//#endregion
|
|
4228
|
+
//#region src/csg/evaluate.ts
|
|
4229
|
+
function dispatch(node, ctx) {
|
|
4230
|
+
switch (node.kind) {
|
|
4231
|
+
case "Box": return evalBox(node, ctx);
|
|
4232
|
+
case "Sphere": return evalSphere(node, ctx);
|
|
4233
|
+
case "Cylinder": return evalCylinder(node, ctx);
|
|
4234
|
+
case "Cone": return evalCone(node, ctx);
|
|
4235
|
+
case "Torus": return evalTorus(node, ctx);
|
|
4236
|
+
case "Polygon": return evalPolygon(node, ctx);
|
|
4237
|
+
case "Circle": return evalCircle(node, ctx);
|
|
4238
|
+
case "Line": return evalLine(node, ctx);
|
|
4239
|
+
case "Vertex": return evalVertex(node, ctx);
|
|
4240
|
+
case "Empty": return evalEmpty();
|
|
4241
|
+
case "Fuse": return evalFuse(node, ctx);
|
|
4242
|
+
case "Cut": return evalCut(node, ctx);
|
|
4243
|
+
case "Intersect": return evalIntersect(node, ctx);
|
|
4244
|
+
case "FuseAll": return evalFuseAll(node, ctx);
|
|
4245
|
+
case "CutAll": return evalCutAll(node, ctx);
|
|
4246
|
+
case "Translate": return evalTranslate(node, ctx);
|
|
4247
|
+
case "Rotate": return evalRotate(node, ctx);
|
|
4248
|
+
case "Scale": return evalScale(node, ctx);
|
|
4249
|
+
case "Mirror": return evalMirror(node, ctx);
|
|
4250
|
+
case "Compound": return evalCompound(node, ctx);
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
function hashExprValue(h, v) {
|
|
4254
|
+
if (typeof v === "number") return fnvMixNumber(fnvMixBool(h, false), v);
|
|
4255
|
+
let r = fnvMixBool(h, true);
|
|
4256
|
+
r = fnvMixInt32(r, v.length);
|
|
4257
|
+
for (const n of v) r = fnvMixNumber(r, n);
|
|
4258
|
+
return r;
|
|
4259
|
+
}
|
|
4260
|
+
function projectedEnvHash(env, deps) {
|
|
4261
|
+
if (deps.size === 0) return fnvInit();
|
|
4262
|
+
const projected = projectEnv(env, deps);
|
|
4263
|
+
const keys = Object.keys(projected).sort();
|
|
4264
|
+
let h = fnvInit();
|
|
4265
|
+
for (const k of keys) {
|
|
4266
|
+
h = fnvMixString(h, k);
|
|
4267
|
+
const v = projected[k];
|
|
4268
|
+
if (v !== void 0) h = hashExprValue(h, v);
|
|
4269
|
+
}
|
|
4270
|
+
return h;
|
|
4271
|
+
}
|
|
4272
|
+
function cacheKey(node, env, kernelId, tolerance) {
|
|
4273
|
+
const projHash = projectedEnvHash(env, node.freeParams);
|
|
4274
|
+
const tolHash = tolerance === void 0 ? "d" : fnvMixNumber(fnvInit(), tolerance).toString(16);
|
|
4275
|
+
return `${toHex(node.structuralHash)}:${kernelId}:${toHex(projHash)}:${tolHash}`;
|
|
4276
|
+
}
|
|
4277
|
+
var Evaluator = class {
|
|
4278
|
+
scope = new DisposalScope();
|
|
4279
|
+
cache = /* @__PURE__ */ new Map();
|
|
4280
|
+
registered = /* @__PURE__ */ new WeakSet();
|
|
4281
|
+
kernelId;
|
|
4282
|
+
defaultTolerance;
|
|
4283
|
+
onStep;
|
|
4284
|
+
hits = 0;
|
|
4285
|
+
misses = 0;
|
|
4286
|
+
constructor(options = {}) {
|
|
4287
|
+
this.kernelId = options.kernel ?? getActiveKernelId() ?? "unregistered";
|
|
4288
|
+
this.defaultTolerance = options.tolerance;
|
|
4289
|
+
if (options.onStep) this.onStep = options.onStep;
|
|
4290
|
+
}
|
|
4291
|
+
/**
|
|
4292
|
+
* Materialize a CSG IR tree against the given parameter environment.
|
|
4293
|
+
* The returned shape is borrowed — valid for as long as this Evaluator is
|
|
4294
|
+
* not disposed. Callers must NOT call `.delete()` / `[Symbol.dispose]()`
|
|
4295
|
+
* on the returned shape; that would invalidate the cache entry for every
|
|
4296
|
+
* future call returning the same handle.
|
|
4297
|
+
*/
|
|
4298
|
+
evaluate(node, env = {}) {
|
|
4299
|
+
return withKernel(this.kernelId, () => this.evaluateInner(node, env));
|
|
4300
|
+
}
|
|
4301
|
+
evaluateInner(node, env) {
|
|
4302
|
+
const key = cacheKey(node, env, this.kernelId, this.defaultTolerance);
|
|
4303
|
+
const cached = this.cache.get(key);
|
|
4304
|
+
if (cached !== void 0) {
|
|
4305
|
+
this.hits++;
|
|
4306
|
+
this.onStep?.({
|
|
4307
|
+
node,
|
|
4308
|
+
cacheKey: key,
|
|
4309
|
+
cacheHit: true
|
|
4310
|
+
});
|
|
4311
|
+
return ok(cached);
|
|
4312
|
+
}
|
|
4313
|
+
this.misses++;
|
|
4314
|
+
const result = dispatch(node, {
|
|
4315
|
+
env,
|
|
4316
|
+
tolerance: this.defaultTolerance,
|
|
4317
|
+
evalNode: (child) => this.evaluateInner(child, env)
|
|
4318
|
+
});
|
|
4319
|
+
if (!result.ok) return result;
|
|
4320
|
+
if (!this.registered.has(result.value)) {
|
|
4321
|
+
this.scope.register(result.value);
|
|
4322
|
+
this.registered.add(result.value);
|
|
4323
|
+
}
|
|
4324
|
+
this.cache.set(key, result.value);
|
|
4325
|
+
this.onStep?.({
|
|
4326
|
+
node,
|
|
4327
|
+
cacheKey: key,
|
|
4328
|
+
cacheHit: false
|
|
4329
|
+
});
|
|
4330
|
+
return result;
|
|
4331
|
+
}
|
|
4332
|
+
cacheStats() {
|
|
4333
|
+
return {
|
|
4334
|
+
hits: this.hits,
|
|
4335
|
+
misses: this.misses,
|
|
4336
|
+
entries: this.cache.size
|
|
4337
|
+
};
|
|
4338
|
+
}
|
|
4339
|
+
resetStats() {
|
|
4340
|
+
this.hits = 0;
|
|
4341
|
+
this.misses = 0;
|
|
4342
|
+
}
|
|
4343
|
+
[Symbol.dispose]() {
|
|
4344
|
+
this.scope[Symbol.dispose]();
|
|
4345
|
+
this.cache.clear();
|
|
4346
|
+
}
|
|
4347
|
+
};
|
|
4348
|
+
/**
|
|
4349
|
+
* Run a callback with a fresh Evaluator that is disposed when the callback
|
|
4350
|
+
* returns. Sync-only: an async callback would resolve after disposal,
|
|
4351
|
+
* leaving borrowed shapes pointing at freed WASM memory. Mirrors the
|
|
4352
|
+
* Promise-guard pattern in `withKernel`.
|
|
4353
|
+
*/
|
|
4354
|
+
function withEvaluator(options, fn) {
|
|
4355
|
+
try {
|
|
4356
|
+
var _usingCtx$1 = _usingCtx();
|
|
4357
|
+
const result = fn(_usingCtx$1.u(new Evaluator(options)));
|
|
4358
|
+
if (result instanceof Promise) throw new Error("withEvaluator() callback returned a Promise. Async code must construct an Evaluator directly and dispose it manually — borrowed shapes would otherwise be freed before the Promise resolves.");
|
|
4359
|
+
return result;
|
|
4360
|
+
} catch (_) {
|
|
4361
|
+
_usingCtx$1.e = _;
|
|
4362
|
+
} finally {
|
|
4363
|
+
_usingCtx$1.d();
|
|
4364
|
+
}
|
|
4365
|
+
}
|
|
4366
|
+
function toJSON(node) {
|
|
4367
|
+
return {
|
|
4368
|
+
csgVersion: 1,
|
|
4369
|
+
root: nodeToJson(node)
|
|
4370
|
+
};
|
|
4371
|
+
}
|
|
4372
|
+
function exprToJson(e) {
|
|
4373
|
+
switch (e.kind) {
|
|
4374
|
+
case "NumLit": return {
|
|
4375
|
+
kind: "NumLit",
|
|
4376
|
+
value: e.value
|
|
4377
|
+
};
|
|
4378
|
+
case "Vec3Lit": return {
|
|
4379
|
+
kind: "Vec3Lit",
|
|
4380
|
+
value: [
|
|
4381
|
+
e.value[0],
|
|
4382
|
+
e.value[1],
|
|
4383
|
+
e.value[2]
|
|
4384
|
+
]
|
|
4385
|
+
};
|
|
4386
|
+
case "Vec2Lit": return {
|
|
4387
|
+
kind: "Vec2Lit",
|
|
4388
|
+
value: [e.value[0], e.value[1]]
|
|
4389
|
+
};
|
|
4390
|
+
case "Param": return {
|
|
4391
|
+
kind: "Param",
|
|
4392
|
+
name: e.name
|
|
4393
|
+
};
|
|
4394
|
+
case "BinOp": return {
|
|
4395
|
+
kind: "BinOp",
|
|
4396
|
+
op: e.op,
|
|
4397
|
+
a: exprToJson(e.a),
|
|
4398
|
+
b: exprToJson(e.b)
|
|
4399
|
+
};
|
|
4400
|
+
case "UnaryOp": return {
|
|
4401
|
+
kind: "UnaryOp",
|
|
4402
|
+
op: e.op,
|
|
4403
|
+
arg: exprToJson(e.arg)
|
|
4404
|
+
};
|
|
4405
|
+
case "Component": return {
|
|
4406
|
+
kind: "Component",
|
|
4407
|
+
vec: exprToJson(e.vec),
|
|
4408
|
+
index: e.index
|
|
4409
|
+
};
|
|
4410
|
+
case "BuildVec": return {
|
|
4411
|
+
kind: "BuildVec",
|
|
4412
|
+
dim: e.dim,
|
|
4413
|
+
components: e.components.map(exprToJson)
|
|
4414
|
+
};
|
|
4415
|
+
}
|
|
4416
|
+
}
|
|
4417
|
+
function primitiveToJson(n) {
|
|
4418
|
+
switch (n.kind) {
|
|
4419
|
+
case "Box": return {
|
|
4420
|
+
kind: "Box",
|
|
4421
|
+
x: exprToJson(n.x),
|
|
4422
|
+
y: exprToJson(n.y),
|
|
4423
|
+
z: exprToJson(n.z)
|
|
4424
|
+
};
|
|
4425
|
+
case "Sphere": return {
|
|
4426
|
+
kind: "Sphere",
|
|
4427
|
+
radius: exprToJson(n.radius)
|
|
4428
|
+
};
|
|
4429
|
+
case "Cylinder": return {
|
|
4430
|
+
kind: "Cylinder",
|
|
4431
|
+
radius: exprToJson(n.radius),
|
|
4432
|
+
height: exprToJson(n.height)
|
|
4433
|
+
};
|
|
4434
|
+
case "Cone": return {
|
|
4435
|
+
kind: "Cone",
|
|
4436
|
+
radius1: exprToJson(n.radius1),
|
|
4437
|
+
radius2: exprToJson(n.radius2),
|
|
4438
|
+
height: exprToJson(n.height)
|
|
4439
|
+
};
|
|
4440
|
+
case "Torus": return {
|
|
4441
|
+
kind: "Torus",
|
|
4442
|
+
majorRadius: exprToJson(n.majorRadius),
|
|
4443
|
+
minorRadius: exprToJson(n.minorRadius)
|
|
4444
|
+
};
|
|
4445
|
+
case "Polygon": return {
|
|
4446
|
+
kind: "Polygon",
|
|
4447
|
+
points: n.points.map(exprToJson)
|
|
4448
|
+
};
|
|
4449
|
+
case "Circle": return {
|
|
4450
|
+
kind: "Circle",
|
|
4451
|
+
radius: exprToJson(n.radius)
|
|
4452
|
+
};
|
|
4453
|
+
case "Line": return {
|
|
4454
|
+
kind: "Line",
|
|
4455
|
+
from: exprToJson(n.from),
|
|
4456
|
+
to: exprToJson(n.to)
|
|
4457
|
+
};
|
|
4458
|
+
case "Vertex": return {
|
|
4459
|
+
kind: "Vertex",
|
|
4460
|
+
point: exprToJson(n.point)
|
|
4461
|
+
};
|
|
4462
|
+
case "Empty": return {
|
|
4463
|
+
kind: "Empty",
|
|
4464
|
+
output: n.output
|
|
4465
|
+
};
|
|
4466
|
+
default: return;
|
|
4467
|
+
}
|
|
4468
|
+
}
|
|
4469
|
+
function booleanToJson(n) {
|
|
4470
|
+
switch (n.kind) {
|
|
4471
|
+
case "Fuse":
|
|
4472
|
+
case "Cut":
|
|
4473
|
+
case "Intersect": return {
|
|
4474
|
+
kind: n.kind,
|
|
4475
|
+
a: nodeToJson(n.a),
|
|
4476
|
+
b: nodeToJson(n.b),
|
|
4477
|
+
tolerance: n.tolerance
|
|
4478
|
+
};
|
|
4479
|
+
case "FuseAll": return {
|
|
4480
|
+
kind: "FuseAll",
|
|
4481
|
+
shapes: n.shapes.map(nodeToJson),
|
|
4482
|
+
tolerance: n.tolerance
|
|
4483
|
+
};
|
|
4484
|
+
case "CutAll": return {
|
|
4485
|
+
kind: "CutAll",
|
|
4486
|
+
base: nodeToJson(n.base),
|
|
4487
|
+
tools: n.tools.map(nodeToJson),
|
|
4488
|
+
tolerance: n.tolerance
|
|
4489
|
+
};
|
|
4490
|
+
default: return;
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
function optExprToJson(e) {
|
|
4494
|
+
return e ? exprToJson(e) : void 0;
|
|
4495
|
+
}
|
|
4496
|
+
function transformToJson(n) {
|
|
4497
|
+
switch (n.kind) {
|
|
4498
|
+
case "Translate": return {
|
|
4499
|
+
kind: "Translate",
|
|
4500
|
+
target: nodeToJson(n.target),
|
|
4501
|
+
vector: exprToJson(n.vector)
|
|
4502
|
+
};
|
|
4503
|
+
case "Rotate": return {
|
|
4504
|
+
kind: "Rotate",
|
|
4505
|
+
target: nodeToJson(n.target),
|
|
4506
|
+
angle: exprToJson(n.angle),
|
|
4507
|
+
axis: optExprToJson(n.axis),
|
|
4508
|
+
at: optExprToJson(n.at)
|
|
4509
|
+
};
|
|
4510
|
+
case "Scale": return {
|
|
4511
|
+
kind: "Scale",
|
|
4512
|
+
target: nodeToJson(n.target),
|
|
4513
|
+
factor: exprToJson(n.factor),
|
|
4514
|
+
center: optExprToJson(n.center)
|
|
4515
|
+
};
|
|
4516
|
+
case "Mirror": return {
|
|
4517
|
+
kind: "Mirror",
|
|
4518
|
+
target: nodeToJson(n.target),
|
|
4519
|
+
normal: optExprToJson(n.normal),
|
|
4520
|
+
at: optExprToJson(n.at)
|
|
4521
|
+
};
|
|
4522
|
+
default: return;
|
|
4523
|
+
}
|
|
4524
|
+
}
|
|
4525
|
+
function nodeToJson(n) {
|
|
4526
|
+
if (n.kind === "Compound") return {
|
|
4527
|
+
kind: "Compound",
|
|
4528
|
+
children: n.children.map(nodeToJson)
|
|
4529
|
+
};
|
|
4530
|
+
return primitiveToJson(n) ?? booleanToJson(n) ?? transformToJson(n);
|
|
4531
|
+
}
|
|
4532
|
+
function bad(msg) {
|
|
4533
|
+
return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `csg.fromJSON: ${msg}`));
|
|
4534
|
+
}
|
|
4535
|
+
function isObj(v) {
|
|
4536
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4537
|
+
}
|
|
4538
|
+
function isNumber$1(v) {
|
|
4539
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
4540
|
+
}
|
|
4541
|
+
function isString(v) {
|
|
4542
|
+
return typeof v === "string";
|
|
4543
|
+
}
|
|
4544
|
+
function readVec3(v, where) {
|
|
4545
|
+
if (!Array.isArray(v) || v.length !== 3) return bad(`${where}: expected Vec3 array`);
|
|
4546
|
+
const [a, b, c] = v;
|
|
4547
|
+
if (!isNumber$1(a) || !isNumber$1(b) || !isNumber$1(c)) return bad(`${where}: Vec3 contains non-number`);
|
|
4548
|
+
return ok([
|
|
4549
|
+
a,
|
|
4550
|
+
b,
|
|
4551
|
+
c
|
|
4552
|
+
]);
|
|
4553
|
+
}
|
|
4554
|
+
function readVec2(v, where) {
|
|
4555
|
+
if (!Array.isArray(v) || v.length !== 2) return bad(`${where}: expected Vec2 array`);
|
|
4556
|
+
const [a, b] = v;
|
|
4557
|
+
if (!isNumber$1(a) || !isNumber$1(b)) return bad(`${where}: Vec2 contains non-number`);
|
|
4558
|
+
return ok([a, b]);
|
|
4559
|
+
}
|
|
4560
|
+
function fromJSON(envelope) {
|
|
4561
|
+
if (!isObj(envelope)) return bad("input is not an object");
|
|
4562
|
+
const v = envelope["csgVersion"];
|
|
4563
|
+
if (v !== 1) return bad(`unsupported csgVersion ${String(v)} (expected 1)`);
|
|
4564
|
+
const root = envelope["root"];
|
|
4565
|
+
return readNode(root);
|
|
4566
|
+
}
|
|
4567
|
+
function readExpr(j) {
|
|
4568
|
+
if (!isObj(j)) return bad("expression: not an object");
|
|
4569
|
+
const kind = j["kind"];
|
|
4570
|
+
switch (kind) {
|
|
4571
|
+
case "NumLit": return isNumber$1(j["value"]) ? ok(numLit(j["value"])) : bad("NumLit.value");
|
|
4572
|
+
case "Vec3Lit": {
|
|
4573
|
+
const v = readVec3(j["value"], "Vec3Lit.value");
|
|
4574
|
+
return v.ok ? ok(vec3Lit(v.value)) : v;
|
|
4575
|
+
}
|
|
4576
|
+
case "Vec2Lit": {
|
|
4577
|
+
const v = readVec2(j["value"], "Vec2Lit.value");
|
|
4578
|
+
return v.ok ? ok(vec2Lit(v.value)) : v;
|
|
4579
|
+
}
|
|
4580
|
+
case "Param": return isString(j["name"]) ? ok(param(j["name"])) : bad("Param.name");
|
|
4581
|
+
case "BinOp": return readBinOp(j);
|
|
4582
|
+
case "UnaryOp": return readUnaryOp(j);
|
|
4583
|
+
case "Component": return readComponent(j);
|
|
4584
|
+
case "BuildVec": return readBuildVec(j);
|
|
4585
|
+
default: return bad(`unknown expression kind: ${String(kind)}`);
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
function readBinOp(j) {
|
|
4589
|
+
const op = j["op"];
|
|
4590
|
+
if (op !== "+" && op !== "-" && op !== "*" && op !== "/") return bad(`BinOp.op: ${String(op)}`);
|
|
4591
|
+
const a = readExpr(j["a"]);
|
|
4592
|
+
if (!a.ok) return a;
|
|
4593
|
+
const b = readExpr(j["b"]);
|
|
4594
|
+
if (!b.ok) return b;
|
|
4595
|
+
return ok(binOp(op, a.value, b.value));
|
|
4596
|
+
}
|
|
4597
|
+
function readUnaryOp(j) {
|
|
4598
|
+
const op = j["op"];
|
|
4599
|
+
if (!isString(op) || ![
|
|
4600
|
+
"neg",
|
|
4601
|
+
"sin",
|
|
4602
|
+
"cos",
|
|
4603
|
+
"sqrt",
|
|
4604
|
+
"abs"
|
|
4605
|
+
].includes(op)) return bad(`UnaryOp.op: ${String(op)}`);
|
|
4606
|
+
const arg = readExpr(j["arg"]);
|
|
4607
|
+
if (!arg.ok) return arg;
|
|
4608
|
+
return ok(unaryOp(op, arg.value));
|
|
4609
|
+
}
|
|
4610
|
+
function readComponent(j) {
|
|
4611
|
+
const index = j["index"];
|
|
4612
|
+
if (index !== 0 && index !== 1 && index !== 2) return bad(`Component.index: ${String(index)}`);
|
|
4613
|
+
const vec = readExpr(j["vec"]);
|
|
4614
|
+
if (!vec.ok) return vec;
|
|
4615
|
+
return ok(component(vec.value, index));
|
|
4616
|
+
}
|
|
4617
|
+
function readBuildVec(j) {
|
|
4618
|
+
const dim = j["dim"];
|
|
4619
|
+
if (dim !== 2 && dim !== 3) return bad(`BuildVec.dim: ${String(dim)}`);
|
|
4620
|
+
const comps = j["components"];
|
|
4621
|
+
if (!Array.isArray(comps)) return bad("BuildVec.components: not array");
|
|
4622
|
+
if (comps.length !== dim) return bad(`BuildVec.components: expected ${dim} components, got ${comps.length}`);
|
|
4623
|
+
const out = [];
|
|
4624
|
+
for (const c of comps) {
|
|
4625
|
+
const r = readExpr(c);
|
|
4626
|
+
if (!r.ok) return r;
|
|
4627
|
+
out.push(r.value);
|
|
4628
|
+
}
|
|
4629
|
+
return ok(buildVec(dim, out));
|
|
4630
|
+
}
|
|
4631
|
+
function readNodeArray(j, where) {
|
|
4632
|
+
if (!Array.isArray(j)) return bad(`${where}: not array`);
|
|
4633
|
+
const out = [];
|
|
4634
|
+
for (const c of j) {
|
|
4635
|
+
const r = readNode(c);
|
|
4636
|
+
if (!r.ok) return r;
|
|
4637
|
+
out.push(r.value);
|
|
4638
|
+
}
|
|
4639
|
+
return ok(out);
|
|
4640
|
+
}
|
|
4641
|
+
function readOptTolerance(j) {
|
|
4642
|
+
const t = j["tolerance"];
|
|
4643
|
+
if (t === void 0 || t === null) return ok(void 0);
|
|
4644
|
+
return isNumber$1(t) ? ok(t) : bad("tolerance: not a finite number");
|
|
4645
|
+
}
|
|
4646
|
+
function readNode(j) {
|
|
4647
|
+
if (!isObj(j)) return bad("node: not an object");
|
|
4648
|
+
const kind = j["kind"];
|
|
4649
|
+
switch (kind) {
|
|
4650
|
+
case "Box":
|
|
4651
|
+
case "Sphere":
|
|
4652
|
+
case "Cylinder":
|
|
4653
|
+
case "Cone":
|
|
4654
|
+
case "Torus":
|
|
4655
|
+
case "Polygon":
|
|
4656
|
+
case "Circle":
|
|
4657
|
+
case "Line":
|
|
4658
|
+
case "Vertex":
|
|
4659
|
+
case "Empty": return readPrimitive(kind, j);
|
|
4660
|
+
case "Fuse":
|
|
4661
|
+
case "Cut":
|
|
4662
|
+
case "Intersect": return readBinaryBool(kind, j);
|
|
4663
|
+
case "FuseAll":
|
|
4664
|
+
case "CutAll": return readNaryBool(kind, j);
|
|
4665
|
+
case "Translate":
|
|
4666
|
+
case "Rotate":
|
|
4667
|
+
case "Scale":
|
|
4668
|
+
case "Mirror": return readTransform(kind, j);
|
|
4669
|
+
case "Compound": return readCompound(j);
|
|
4670
|
+
default: return bad(`unknown node kind: ${String(kind)}`);
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
function readSingleExpr(j, key, build) {
|
|
4674
|
+
const r = readExpr(j[key]);
|
|
4675
|
+
return r.ok ? ok(build(r.value)) : r;
|
|
4676
|
+
}
|
|
4677
|
+
function readPrimitive(kind, j) {
|
|
4678
|
+
switch (kind) {
|
|
4679
|
+
case "Box": return readBox(j);
|
|
4680
|
+
case "Sphere": return readSingleExpr(j, "radius", sphere$1);
|
|
4681
|
+
case "Cylinder": return readCylinder(j);
|
|
4682
|
+
case "Cone": return readCone(j);
|
|
4683
|
+
case "Torus": return readTorus(j);
|
|
4684
|
+
case "Polygon": return readPolygon(j);
|
|
4685
|
+
case "Circle": return readSingleExpr(j, "radius", circle$1);
|
|
4686
|
+
case "Line": return readLine(j);
|
|
4687
|
+
case "Vertex": return readSingleExpr(j, "point", vertex$1);
|
|
4688
|
+
case "Empty": return readEmpty(j);
|
|
4689
|
+
}
|
|
4690
|
+
return bad(`unhandled primitive: ${kind}`);
|
|
4691
|
+
}
|
|
4692
|
+
function readBox(j) {
|
|
4693
|
+
const x = readExpr(j["x"]);
|
|
4694
|
+
if (!x.ok) return x;
|
|
4695
|
+
const y = readExpr(j["y"]);
|
|
4696
|
+
if (!y.ok) return y;
|
|
4697
|
+
const z = readExpr(j["z"]);
|
|
4698
|
+
if (!z.ok) return z;
|
|
4699
|
+
return ok(box$1(x.value, y.value, z.value));
|
|
4700
|
+
}
|
|
4701
|
+
function readCylinder(j) {
|
|
4702
|
+
const r = readExpr(j["radius"]);
|
|
4703
|
+
if (!r.ok) return r;
|
|
4704
|
+
const h = readExpr(j["height"]);
|
|
4705
|
+
if (!h.ok) return h;
|
|
4706
|
+
return ok(cylinder$1(r.value, h.value));
|
|
4707
|
+
}
|
|
4708
|
+
function readCone(j) {
|
|
4709
|
+
const r1 = readExpr(j["radius1"]);
|
|
4710
|
+
if (!r1.ok) return r1;
|
|
4711
|
+
const r2 = readExpr(j["radius2"]);
|
|
4712
|
+
if (!r2.ok) return r2;
|
|
4713
|
+
const h = readExpr(j["height"]);
|
|
4714
|
+
if (!h.ok) return h;
|
|
4715
|
+
return ok(cone$1(r1.value, r2.value, h.value));
|
|
4716
|
+
}
|
|
4717
|
+
function readTorus(j) {
|
|
4718
|
+
const ma = readExpr(j["majorRadius"]);
|
|
4719
|
+
if (!ma.ok) return ma;
|
|
4720
|
+
const mi = readExpr(j["minorRadius"]);
|
|
4721
|
+
if (!mi.ok) return mi;
|
|
4722
|
+
return ok(torus$1(ma.value, mi.value));
|
|
4723
|
+
}
|
|
4724
|
+
function readPolygon(j) {
|
|
4725
|
+
const pts = j["points"];
|
|
4726
|
+
if (!Array.isArray(pts)) return bad("Polygon.points: not array");
|
|
4727
|
+
const out = [];
|
|
4728
|
+
for (const p of pts) {
|
|
4729
|
+
const r = readExpr(p);
|
|
4730
|
+
if (!r.ok) return r;
|
|
4731
|
+
out.push(r.value);
|
|
4732
|
+
}
|
|
4733
|
+
return ok(polygon$1(out));
|
|
4734
|
+
}
|
|
4735
|
+
function readLine(j) {
|
|
4736
|
+
const f = readExpr(j["from"]);
|
|
4737
|
+
if (!f.ok) return f;
|
|
4738
|
+
const t = readExpr(j["to"]);
|
|
4739
|
+
if (!t.ok) return t;
|
|
4740
|
+
return ok(line$1(f.value, t.value));
|
|
4741
|
+
}
|
|
4742
|
+
function readEmpty(j) {
|
|
4743
|
+
const out = j["output"];
|
|
4744
|
+
switch (out) {
|
|
4745
|
+
case "Solid": return ok(emptySolid());
|
|
4746
|
+
case "Face": return ok(emptyFace());
|
|
4747
|
+
case "Wire": return ok(emptyWire());
|
|
4748
|
+
default: return bad(`Empty.output: ${String(out)}`);
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
function readBinaryBool(kind, j) {
|
|
4752
|
+
const a = readNode(j["a"]);
|
|
4753
|
+
if (!a.ok) return a;
|
|
4754
|
+
const b = readNode(j["b"]);
|
|
4755
|
+
if (!b.ok) return b;
|
|
4756
|
+
const t = readOptTolerance(j);
|
|
4757
|
+
if (!t.ok) return t;
|
|
4758
|
+
switch (kind) {
|
|
4759
|
+
case "Fuse": return ok(fuse$1(a.value, b.value, t.value));
|
|
4760
|
+
case "Cut": return ok(cut$1(a.value, b.value, t.value));
|
|
4761
|
+
case "Intersect": return ok(intersect$1(a.value, b.value, t.value));
|
|
4762
|
+
}
|
|
4763
|
+
}
|
|
4764
|
+
function readNaryBool(kind, j) {
|
|
4765
|
+
const t = readOptTolerance(j);
|
|
4766
|
+
if (!t.ok) return t;
|
|
4767
|
+
if (kind === "FuseAll") {
|
|
4768
|
+
const shapes = readNodeArray(j["shapes"], "FuseAll.shapes");
|
|
4769
|
+
return shapes.ok ? ok(fuseAll$1(shapes.value, t.value)) : shapes;
|
|
4770
|
+
}
|
|
4771
|
+
const base = readNode(j["base"]);
|
|
4772
|
+
if (!base.ok) return base;
|
|
4773
|
+
const tools = readNodeArray(j["tools"], "CutAll.tools");
|
|
4774
|
+
return tools.ok ? ok(cutAll$1(base.value, tools.value, t.value)) : tools;
|
|
4775
|
+
}
|
|
4776
|
+
function readTransform(kind, j) {
|
|
4777
|
+
const tgt = readNode(j["target"]);
|
|
4778
|
+
if (!tgt.ok) return tgt;
|
|
4779
|
+
switch (kind) {
|
|
4780
|
+
case "Translate": return readTranslate(j, tgt.value);
|
|
4781
|
+
case "Rotate": return readRotate(j, tgt.value);
|
|
4782
|
+
case "Scale": return readScale(j, tgt.value);
|
|
4783
|
+
case "Mirror": return readMirror(j, tgt.value);
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4786
|
+
function readTranslate(j, target) {
|
|
4787
|
+
const v = readExpr(j["vector"]);
|
|
4788
|
+
return v.ok ? ok(translate$1(target, v.value)) : v;
|
|
4789
|
+
}
|
|
4790
|
+
function readOptExpr(j, key) {
|
|
4791
|
+
if (j[key] === void 0) return ok(void 0);
|
|
4792
|
+
const r = readExpr(j[key]);
|
|
4793
|
+
return r.ok ? ok(r.value) : r;
|
|
4794
|
+
}
|
|
4795
|
+
function readRotate(j, target) {
|
|
4796
|
+
const ang = readExpr(j["angle"]);
|
|
4797
|
+
if (!ang.ok) return ang;
|
|
4798
|
+
const axis = readOptExpr(j, "axis");
|
|
4799
|
+
if (!axis.ok) return axis;
|
|
4800
|
+
const at = readOptExpr(j, "at");
|
|
4801
|
+
if (!at.ok) return at;
|
|
4802
|
+
return ok(rotate$1(target, ang.value, {
|
|
4803
|
+
axis: axis.value,
|
|
4804
|
+
at: at.value
|
|
4805
|
+
}));
|
|
4806
|
+
}
|
|
4807
|
+
function readScale(j, target) {
|
|
4808
|
+
const f = readExpr(j["factor"]);
|
|
4809
|
+
if (!f.ok) return f;
|
|
4810
|
+
const center = readOptExpr(j, "center");
|
|
4811
|
+
if (!center.ok) return center;
|
|
4812
|
+
return ok(scale$1(target, f.value, { center: center.value }));
|
|
4813
|
+
}
|
|
4814
|
+
function readMirror(j, target) {
|
|
4815
|
+
const normal = readOptExpr(j, "normal");
|
|
4816
|
+
if (!normal.ok) return normal;
|
|
4817
|
+
const at = readOptExpr(j, "at");
|
|
4818
|
+
if (!at.ok) return at;
|
|
4819
|
+
return ok(mirror$1(target, {
|
|
4820
|
+
normal: normal.value,
|
|
4821
|
+
at: at.value
|
|
4822
|
+
}));
|
|
4823
|
+
}
|
|
4824
|
+
function readCompound(j) {
|
|
4825
|
+
const children = readNodeArray(j["children"], "Compound.children");
|
|
4826
|
+
return children.ok ? ok(compound$1(children.value)) : children;
|
|
4827
|
+
}
|
|
4828
|
+
//#endregion
|
|
4829
|
+
//#region src/csg/optimize.ts
|
|
4830
|
+
function optimize(node) {
|
|
4831
|
+
return optimizeNode(node);
|
|
4832
|
+
}
|
|
4833
|
+
function foldExpr(e) {
|
|
4834
|
+
switch (e.kind) {
|
|
4835
|
+
case "NumLit":
|
|
4836
|
+
case "Vec3Lit":
|
|
4837
|
+
case "Vec2Lit":
|
|
4838
|
+
case "Param": return e;
|
|
4839
|
+
case "BinOp": {
|
|
4840
|
+
const a = foldExpr(e.a);
|
|
4841
|
+
const b = foldExpr(e.b);
|
|
4842
|
+
if (a.kind === "NumLit" && b.kind === "NumLit") switch (e.op) {
|
|
4843
|
+
case "+": return numLit(a.value + b.value);
|
|
4844
|
+
case "-": return numLit(a.value - b.value);
|
|
4845
|
+
case "*": return numLit(a.value * b.value);
|
|
4846
|
+
case "/": return numLit(a.value / b.value);
|
|
4847
|
+
}
|
|
4848
|
+
if (a !== e.a || b !== e.b) return binOp(e.op, a, b);
|
|
4849
|
+
return e;
|
|
4850
|
+
}
|
|
4851
|
+
case "UnaryOp": {
|
|
4852
|
+
const arg = foldExpr(e.arg);
|
|
4853
|
+
if (arg.kind === "NumLit") {
|
|
4854
|
+
const n = arg.value;
|
|
4855
|
+
switch (e.op) {
|
|
4856
|
+
case "neg": return numLit(-n);
|
|
4857
|
+
case "sin": return numLit(Math.sin(n));
|
|
4858
|
+
case "cos": return numLit(Math.cos(n));
|
|
4859
|
+
case "sqrt": return numLit(Math.sqrt(n));
|
|
4860
|
+
case "abs": return numLit(Math.abs(n));
|
|
4861
|
+
}
|
|
4862
|
+
}
|
|
4863
|
+
if (arg !== e.arg) return unaryOp(e.op, arg);
|
|
4864
|
+
return e;
|
|
4865
|
+
}
|
|
4866
|
+
case "Component": {
|
|
4867
|
+
const v = foldExpr(e.vec);
|
|
4868
|
+
if (v.kind === "Vec3Lit") return numLit(v.value[e.index]);
|
|
4869
|
+
if (v.kind === "Vec2Lit" && (e.index === 0 || e.index === 1)) return numLit(v.value[e.index]);
|
|
4870
|
+
if (v !== e.vec) return component(v, e.index);
|
|
4871
|
+
return e;
|
|
4872
|
+
}
|
|
4873
|
+
case "BuildVec": {
|
|
4874
|
+
const folded = e.components.map(foldExpr);
|
|
4875
|
+
const collapsed = foldBuildVec(e.dim, folded);
|
|
4876
|
+
if (collapsed) return collapsed;
|
|
4877
|
+
if (folded.some((c, i) => c !== e.components[i])) return buildVec(e.dim, folded);
|
|
4878
|
+
return e;
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
}
|
|
4882
|
+
function foldBuildVec(dim, comps) {
|
|
4883
|
+
if (comps.length !== dim) return void 0;
|
|
4884
|
+
const nums = [];
|
|
4885
|
+
for (const c of comps) {
|
|
4886
|
+
if (c.kind !== "NumLit") return void 0;
|
|
4887
|
+
nums.push(c.value);
|
|
4888
|
+
}
|
|
4889
|
+
if (dim === 2) return vec2Lit([nums[0], nums[1]]);
|
|
4890
|
+
return vec3Lit([
|
|
4891
|
+
nums[0],
|
|
4892
|
+
nums[1],
|
|
4893
|
+
nums[2]
|
|
4894
|
+
]);
|
|
4895
|
+
}
|
|
4896
|
+
function optimizeNode(n) {
|
|
4897
|
+
switch (n.kind) {
|
|
4898
|
+
case "Box": return box$1(foldExpr(n.x), foldExpr(n.y), foldExpr(n.z));
|
|
4899
|
+
case "Sphere": return sphere$1(foldExpr(n.radius));
|
|
4900
|
+
case "Cylinder": return cylinder$1(foldExpr(n.radius), foldExpr(n.height));
|
|
4901
|
+
case "Cone": return cone$1(foldExpr(n.radius1), foldExpr(n.radius2), foldExpr(n.height));
|
|
4902
|
+
case "Torus": return torus$1(foldExpr(n.majorRadius), foldExpr(n.minorRadius));
|
|
4903
|
+
case "Polygon": return polygon$1(n.points.map(foldExpr));
|
|
4904
|
+
case "Circle": return circle$1(foldExpr(n.radius));
|
|
4905
|
+
case "Line": return line$1(foldExpr(n.from), foldExpr(n.to));
|
|
4906
|
+
case "Vertex": return vertex$1(foldExpr(n.point));
|
|
4907
|
+
case "Empty": return n;
|
|
4908
|
+
case "Fuse": return optimizeFuse(n.a, n.b, n.tolerance);
|
|
4909
|
+
case "Cut": return optimizeCut(n.a, n.b, n.tolerance);
|
|
4910
|
+
case "Intersect": return optimizeIntersect(n.a, n.b, n.tolerance);
|
|
4911
|
+
case "FuseAll": return optimizeFuseAll(n.shapes, n.tolerance);
|
|
4912
|
+
case "CutAll": return optimizeCutAll(n.base, n.tools, n.tolerance);
|
|
4913
|
+
case "Translate": return optimizeTranslate(n.target, n.vector);
|
|
4914
|
+
case "Rotate": return rotate$1(optimizeNode(n.target), foldExpr(n.angle), {
|
|
4915
|
+
axis: n.axis ? foldExpr(n.axis) : void 0,
|
|
4916
|
+
at: n.at ? foldExpr(n.at) : void 0
|
|
4917
|
+
});
|
|
4918
|
+
case "Scale": return scale$1(optimizeNode(n.target), foldExpr(n.factor), { center: n.center ? foldExpr(n.center) : void 0 });
|
|
4919
|
+
case "Mirror": return mirror$1(optimizeNode(n.target), {
|
|
4920
|
+
normal: n.normal ? foldExpr(n.normal) : void 0,
|
|
4921
|
+
at: n.at ? foldExpr(n.at) : void 0
|
|
4922
|
+
});
|
|
4923
|
+
case "Compound": return compound$1(n.children.map(optimizeNode).filter((c) => c.kind !== "Empty"));
|
|
4924
|
+
}
|
|
4925
|
+
}
|
|
4926
|
+
function optimizeFuse(a, b, tol) {
|
|
4927
|
+
const oa = optimizeNode(a);
|
|
4928
|
+
const ob = optimizeNode(b);
|
|
4929
|
+
if (oa.kind === "Empty") return ob;
|
|
4930
|
+
if (ob.kind === "Empty") return oa;
|
|
4931
|
+
return fuse$1(oa, ob, tol);
|
|
4932
|
+
}
|
|
4933
|
+
function optimizeCut(a, b, tol) {
|
|
4934
|
+
const oa = optimizeNode(a);
|
|
4935
|
+
const ob = optimizeNode(b);
|
|
4936
|
+
if (ob.kind === "Empty") return oa;
|
|
4937
|
+
if (oa.kind === "Empty") return oa;
|
|
4938
|
+
return cut$1(oa, ob, tol);
|
|
4939
|
+
}
|
|
4940
|
+
function optimizeIntersect(a, b, tol) {
|
|
4941
|
+
const oa = optimizeNode(a);
|
|
4942
|
+
const ob = optimizeNode(b);
|
|
4943
|
+
if (oa.kind === "Empty") return oa;
|
|
4944
|
+
if (ob.kind === "Empty") return ob;
|
|
4945
|
+
return intersect$1(oa, ob, tol);
|
|
4946
|
+
}
|
|
4947
|
+
function optimizeFuseAll(shapes, tol) {
|
|
4948
|
+
const opt = shapes.map(optimizeNode).filter((s) => s.kind !== "Empty");
|
|
4949
|
+
if (opt.length === 0) return emptySolid();
|
|
4950
|
+
if (opt.length === 1) return opt[0];
|
|
4951
|
+
return fuseAll$1(opt, tol);
|
|
4952
|
+
}
|
|
4953
|
+
function optimizeCutAll(base, tools, tol) {
|
|
4954
|
+
const ob = optimizeNode(base);
|
|
4955
|
+
if (ob.kind === "Empty") return ob;
|
|
4956
|
+
const ot = tools.map(optimizeNode).filter((s) => s.kind !== "Empty");
|
|
4957
|
+
if (ot.length === 0) return ob;
|
|
4958
|
+
return cutAll$1(ob, ot, tol);
|
|
4959
|
+
}
|
|
4960
|
+
function optimizeTranslate(target, vector) {
|
|
4961
|
+
const ot = optimizeNode(target);
|
|
4962
|
+
const ov = foldExpr(vector);
|
|
4963
|
+
if (ov.kind !== "Vec3Lit") return translate$1(ot, ov);
|
|
4964
|
+
const [x, y, z] = ov.value;
|
|
4965
|
+
if (x === 0 && y === 0 && z === 0) return ot;
|
|
4966
|
+
if (ot.kind === "Translate") {
|
|
4967
|
+
const inner = foldExpr(ot.vector);
|
|
4968
|
+
if (inner.kind === "Vec3Lit") return translate$1(ot.target, [
|
|
4969
|
+
inner.value[0] + x,
|
|
4970
|
+
inner.value[1] + y,
|
|
4971
|
+
inner.value[2] + z
|
|
4972
|
+
]);
|
|
4973
|
+
}
|
|
4974
|
+
return translate$1(ot, ov);
|
|
4975
|
+
}
|
|
4976
|
+
//#endregion
|
|
4977
|
+
//#region src/csg/edit.ts
|
|
4978
|
+
function replaceNode(root, pred, replacement) {
|
|
4979
|
+
return walk(root, pred, replacement);
|
|
4980
|
+
}
|
|
4981
|
+
function walk(node, pred, repl) {
|
|
4982
|
+
if (pred(node)) return repl;
|
|
4983
|
+
return rebuildChildren(node, pred, repl);
|
|
4984
|
+
}
|
|
4985
|
+
function rebuildChildren(n, pred, repl) {
|
|
4986
|
+
switch (n.kind) {
|
|
4987
|
+
case "Box":
|
|
4988
|
+
case "Sphere":
|
|
4989
|
+
case "Cylinder":
|
|
4990
|
+
case "Cone":
|
|
4991
|
+
case "Torus":
|
|
4992
|
+
case "Polygon":
|
|
4993
|
+
case "Circle":
|
|
4994
|
+
case "Line":
|
|
4995
|
+
case "Vertex":
|
|
4996
|
+
case "Empty": return n;
|
|
4997
|
+
case "Fuse": return fuse$1(walk(n.a, pred, repl), walk(n.b, pred, repl), n.tolerance);
|
|
4998
|
+
case "Cut": return cut$1(walk(n.a, pred, repl), walk(n.b, pred, repl), n.tolerance);
|
|
4999
|
+
case "Intersect": return intersect$1(walk(n.a, pred, repl), walk(n.b, pred, repl), n.tolerance);
|
|
5000
|
+
case "FuseAll": return fuseAll$1(n.shapes.map((c) => walk(c, pred, repl)), n.tolerance);
|
|
5001
|
+
case "CutAll": return cutAll$1(walk(n.base, pred, repl), n.tools.map((c) => walk(c, pred, repl)), n.tolerance);
|
|
5002
|
+
case "Translate": return translate$1(walk(n.target, pred, repl), n.vector);
|
|
5003
|
+
case "Rotate": return rotate$1(walk(n.target, pred, repl), n.angle, {
|
|
5004
|
+
axis: n.axis,
|
|
5005
|
+
at: n.at
|
|
5006
|
+
});
|
|
5007
|
+
case "Scale": return scale$1(walk(n.target, pred, repl), n.factor, { center: n.center });
|
|
5008
|
+
case "Mirror": return mirror$1(walk(n.target, pred, repl), {
|
|
5009
|
+
normal: n.normal,
|
|
5010
|
+
at: n.at
|
|
5011
|
+
});
|
|
5012
|
+
case "Compound": return compound$1(n.children.map((c) => walk(c, pred, repl)));
|
|
5013
|
+
}
|
|
5014
|
+
}
|
|
5015
|
+
function forEachNode(root, fn) {
|
|
5016
|
+
fn(root);
|
|
5017
|
+
for (const child of childrenOf(root)) forEachNode(child, fn);
|
|
5018
|
+
}
|
|
5019
|
+
function childrenOf(n) {
|
|
5020
|
+
switch (n.kind) {
|
|
5021
|
+
case "Box":
|
|
5022
|
+
case "Sphere":
|
|
5023
|
+
case "Cylinder":
|
|
5024
|
+
case "Cone":
|
|
5025
|
+
case "Torus":
|
|
5026
|
+
case "Polygon":
|
|
5027
|
+
case "Circle":
|
|
5028
|
+
case "Line":
|
|
5029
|
+
case "Vertex":
|
|
5030
|
+
case "Empty": return [];
|
|
5031
|
+
case "Fuse":
|
|
5032
|
+
case "Cut":
|
|
5033
|
+
case "Intersect": return [n.a, n.b];
|
|
5034
|
+
case "FuseAll": return n.shapes;
|
|
5035
|
+
case "CutAll": return [n.base, ...n.tools];
|
|
5036
|
+
case "Translate":
|
|
5037
|
+
case "Rotate":
|
|
5038
|
+
case "Scale":
|
|
5039
|
+
case "Mirror": return [n.target];
|
|
5040
|
+
case "Compound": return n.children;
|
|
5041
|
+
}
|
|
5042
|
+
}
|
|
5043
|
+
function nodeCount(root) {
|
|
5044
|
+
let n = 0;
|
|
5045
|
+
forEachNode(root, () => {
|
|
5046
|
+
n++;
|
|
5047
|
+
});
|
|
5048
|
+
return n;
|
|
5049
|
+
}
|
|
5050
|
+
//#endregion
|
|
5051
|
+
//#region src/ns/csg.ts
|
|
5052
|
+
var csg_exports = /* @__PURE__ */ __exportAll({
|
|
5053
|
+
CSG_VERSION: () => 1,
|
|
5054
|
+
Evaluator: () => Evaluator,
|
|
5055
|
+
add: () => add,
|
|
5056
|
+
asScalarExpr: () => asScalarExpr,
|
|
5057
|
+
asVec2Expr: () => asVec2Expr,
|
|
5058
|
+
asVec3Expr: () => asVec3Expr,
|
|
5059
|
+
binOp: () => binOp,
|
|
5060
|
+
box: () => box$1,
|
|
5061
|
+
buildVec: () => buildVec,
|
|
5062
|
+
circle: () => circle$1,
|
|
5063
|
+
component: () => component,
|
|
5064
|
+
compound: () => compound$1,
|
|
5065
|
+
cone: () => cone$1,
|
|
5066
|
+
cut: () => cut$1,
|
|
5067
|
+
cutAll: () => cutAll$1,
|
|
5068
|
+
cylinder: () => cylinder$1,
|
|
5069
|
+
emptyFace: () => emptyFace,
|
|
5070
|
+
emptySolid: () => emptySolid,
|
|
5071
|
+
emptyWire: () => emptyWire,
|
|
5072
|
+
foldExpr: () => foldExpr,
|
|
5073
|
+
forEachNode: () => forEachNode,
|
|
5074
|
+
fromJSON: () => fromJSON,
|
|
5075
|
+
fuse: () => fuse$1,
|
|
5076
|
+
fuseAll: () => fuseAll$1,
|
|
5077
|
+
intersect: () => intersect$1,
|
|
5078
|
+
line: () => line$1,
|
|
5079
|
+
mirror: () => mirror$1,
|
|
5080
|
+
mul: () => mul,
|
|
5081
|
+
nodeCount: () => nodeCount,
|
|
5082
|
+
numLit: () => numLit,
|
|
5083
|
+
optimize: () => optimize,
|
|
5084
|
+
outputKindOf: () => outputKindOf,
|
|
5085
|
+
param: () => param,
|
|
5086
|
+
polygon: () => polygon$1,
|
|
5087
|
+
replaceNode: () => replaceNode,
|
|
5088
|
+
rotate: () => rotate$1,
|
|
5089
|
+
scale: () => scale$1,
|
|
5090
|
+
sphere: () => sphere$1,
|
|
5091
|
+
toJSON: () => toJSON,
|
|
5092
|
+
torus: () => torus$1,
|
|
5093
|
+
translate: () => translate$1,
|
|
5094
|
+
unaryOp: () => unaryOp,
|
|
5095
|
+
vec2Lit: () => vec2Lit,
|
|
5096
|
+
vec3Lit: () => vec3Lit,
|
|
5097
|
+
vertex: () => vertex$1,
|
|
5098
|
+
withEvaluator: () => withEvaluator
|
|
5099
|
+
});
|
|
5100
|
+
//#endregion
|
|
5101
|
+
export { BaseSketcher2d, BlueprintSketcher, BrepBugError, BrepErrorCode, BrepWrapperError, BrepkitAdapter, CompoundSketch, DEG2RAD, DisposalScope, FaceSketcher, HASH_CODE_MAX, OK, OcctWasmAdapter, RAD2DEG, Sketch, Sketcher, Sketches, addChild, addHoles, addMate, addStep, adjacentFaces, all, andThen, applyGlue, applyMatrix, approximateCurve, as2D, as3D, asTopo, assignRoles, autoHeal, bezier, blueprintToDXF, booleanPipeline, booleans_exports as booleans, boss, box, bsplineApprox, bug, cameraFromPlane, cameraLookAt, captureHint, cast, castShape, castShape3D, chamfer, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkAllInterferences, checkBoolean, checkInterference, circle, circularPattern, classifyPointOnFace, clearMeshCache, clone, closedWire, collect, collectShapes, colorFaces, colorShape, complexExtrude, composeTransforms, compound, compoundSketchExtrude, compoundSketchFace, compoundSketchLoft, compoundSketchRevolve, computationError, computeStraightSkeleton, cone, construction_exports as construction, convexHull, cornerFinder, countNodes, createAssembly, createAssemblyNode, createBlueprint, createCamera, createCompound, createCompoundBlueprint, createDistanceQuery, createEdge, createFace, createHandle, createHistory, createKernelHandle, createMeshCache, createNamedPlane, createOperationRegistry, createPlane, createRef, createRegistry, createShell, createSolid, createTaskQueue, createVertex, createWire, createWorkerClient, createWorkerHandler, csg_exports as csg, curve2dBoundingBox, curve2dDistanceFrom, curve2dFirstPoint, curve2dIsOnCurve, curve2dLastPoint, curve2dParameter, curve2dSplitAt, curve2dTangentAt, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cut, cut2D, cutAll, cutAllBisect, cutBlueprints, cutWithEvolution, cylinder, defaultScorer, dequeueTask, describe, deserializeDrawing, deserializeHistory, fromBREP as deserializeShape, downcast, draft, draw, drawCircle, drawEllipse, drawFaceOutline, drawParametricFunction, drawPointsInterpolation, drawPolysides, drawProjection, drawRectangle, drawRoundedRectangle, drawSingleCircle, drawSingleEllipse, drawText, drawingChamfer, drawingCut, drawingFillet, drawingFuse, drawingIntersect, drawingToSketchOnPlane, drill, edgeFinder, edgesOfFace, ellipse, ellipseArc, ellipsoid, enqueueTask, err, exportAssemblySTEP, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, extrude, extrudeAll, face, faceCenter, faceFinder, faceGeomType, faceOrientation, facesOfEdge, fill, filledFace, fillet, filletWithEvolution, findFacesByTag, findNode, findStep, fixSelfIntersection, fixShape, flatMap, flatten, flipFaceOrientation, flipOrientation, fontMetrics, fromBREP$1 as fromBREP, fromKernelDir, fromKernelPnt, fromKernelVec, fromNullable, fuse, fuse2D, fuseAll, fuseAllBisect, fuseBlueprints, fuseWithEvolution, gearGeometry, getBounds, getBounds2D, getCurveType, getDisposalStats, getEdges, getFaceColor, getFaceOrigins, getFaceTags, getFaces, getFont, getHashCode, getShape as getHistoryShape, getKernel, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getOrientation2D, getPerformanceStats, getShapeColor, getShapeKind, getSingleFace, getSurfaceType, getTagMetadata, getVertices, getWires, guidedSweep, heal, healFace, healSolid, healWire, helix, hull, importDXF, importGLB, importIGES, importOBJ, importSTEP, importSTL, importSVG, importSVGPathD, importThreeMF, init, initFromOC, innerWires, interpolateCurve, intersect, intersect2D, intersectBlueprints, intersectWithEvolution, invalidateShapeCache, ioNs_exports as io, ioError, is2D, is3D, isChamferRadius, isClosedWire, isCompSolid, isCompound, isDisposeRequest, isEdge, isEmpty, isEqualShape, isErr, isErrorResponse, isFace, isFilletRadius, isInitRequest, isInside2D, isLive, isManifoldShell, isNumber, isOk, isOperationRequest, isOrientedFace, isPlanarFace, isPlanarWire, isProjectionPlane, isEmpty$1 as isQueueEmpty, isSameShape, isShape1D, isShape3D, isShell, isSolid, isSuccessResponse, isValid, isValidSolid, isVertex, isWire, iterEdges, iterFaces, iterTopo, iterVertices, iterWires, kernelCall, kernelCallRaw, kernelCallScoped, kernelError, line, linearPattern, loadFont, loft, loftAll, makeBaseBox, makeExternalGear, makeInternalGear, makePlane, makePlanetaryGear, makeProjectedEdges, manifoldShell, map, mapBoth, mapErr, match, measureArea, measureCurvatureAt, measureCurvatureAtMid, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, measurement_exports as measurement, mesh, meshEdges, meshMultiLOD, minkowski, mirror, mirror2D, mirrorDrawing, mirrorJoin, modifiers_exports as modifiers, modifyStep, moduleInitError, multiSectionSweep, normalAt, offset, offsetFace, offsetWire2D, ok, or, orElse, organiseBlueprints, orientedFace, outerWire, patterns_exports as patterns, pendingCount, pipeline, pivotPlane, planarFace, planarWire, planetPlacements, pocket, pointOnSurface, polygon, polyhedron, polysideInnerRadius, polysidesBlueprint, positionOnCurve, prewarm, primitives_exports as primitives, projectEdges, projectPointOnFace, query_exports as query, queryError, rectangularPattern, registerHandler, registerKernel, registerOperation, registerShape, rejectAll, removeChild, removeHolesFromFace, replayFrom, replayHistory, resetDisposalStats, resetPerformanceStats, resize, resolve, resolve3D, resolveDirection, resolvePlane, resolveRef, reverseCurve, revolve, roof, rotate, rotate2D, rotateDrawing, roundedRectangleBlueprint, scale, scale2D, scaleDrawing, section, sectionToFace, serializeHistory, setShapeOrigin, setTagMetadata, sewShells, shape, shapeType, sharedEdges, shell, shellWithEvolution, simplify, sketchCircle, sketchEllipse, sketchExtrude, sketchFace, sketchFaceOffset, sketchHelix, sketchLoft, sketchOnFace2D, sketchOnPlane2D, sketchParametricFunction, sketchPolysides, sketchRectangle, sketchRevolve, sketchRoundedRectangle, sketchSweep, sketchText, sketchWires, sketcherStateError, slice, solid, solidFromShell, solveAssembly, sphere, split, stepCount, stepsFrom, stretch2D, subFace, supportExtrude, supportsConstraintSketch, supportsProjection, surfaceFromGrid, surfaceFromImage, sweep, tagFaces, tangentArc, tap, tapErr, textBlueprints, textMetrics, thicken, threePointArc, toBREP, toBufferGeometryData, toGroupedBufferGeometryData, toKernelVec, toLODGeometryData, toLineGeometryData, toSVGPathD, toVec2, toVec3, torus, transformCopy, transforms_exports as transforms, translate, translate2D, translateDrawing, translatePlane, tryCatch, tryCatchAsync, twistExtrude, typeCastError, undoLast, unsupportedError, unwrap, unwrapErr, unwrapOr, unwrapOrElse, updateNode, updateRoles, uvBounds, uvCoordinates, validSolid, validatePlanetary, validationError, variableFillet, vecAdd, vecAngle, vecCross, vecDistance, vecDot, vecEquals, vecIsZero, vecLength, vecLengthSq, vecNegate, vecNormalize, vecProjectToPlane, vecRepr, vecRotate, vecScale, vecSub, vertex, vertexFinder, vertexPosition, verticesOfEdge, walkAssembly, wire, wireFinder, wireLoop, wiresOfFace, withKernel, withKernelDir, withKernelPnt, withKernelVec, withScope, withScopeResult, withScopeResultAsync, zip as zipResults };
|