brepjs 18.6.1 → 18.14.3
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 +6 -0
- package/dist/{sketching/sketcher2d.d.ts → 2d/blueprints/baseSketcher2d.d.ts} +4 -91
- package/dist/2d/blueprints/blueprint.d.ts +0 -1
- package/dist/2d/blueprints/blueprintApproximations.d.ts +0 -1
- package/dist/2d/blueprints/blueprintCustomCorners.d.ts +0 -1
- package/dist/2d/blueprints/blueprintFns.d.ts +0 -1
- package/dist/2d/blueprints/blueprintOffset.d.ts +0 -1
- package/dist/2d/blueprints/blueprintSketcher.d.ts +29 -0
- package/dist/2d/blueprints/blueprints.d.ts +0 -1
- package/dist/2d/blueprints/boolean2D.d.ts +0 -1
- package/dist/2d/blueprints/booleanHelpers.d.ts +0 -1
- package/dist/2d/blueprints/booleanOperations.d.ts +0 -1
- package/dist/2d/blueprints/cannedBlueprints.d.ts +0 -1
- package/dist/2d/blueprints/compoundBlueprint.d.ts +0 -1
- package/dist/{sketching → 2d/blueprints}/ellipseUtils.d.ts +19 -2
- package/dist/{sketching/sketcherlib.d.ts → 2d/blueprints/genericSketcher.d.ts} +1 -20
- package/dist/2d/blueprints/index.d.ts +0 -1
- package/dist/2d/blueprints/intersectionSegments.d.ts +0 -1
- package/dist/2d/blueprints/lib.d.ts +0 -1
- package/dist/2d/blueprints/segmentAssembly.d.ts +0 -1
- package/dist/2d/blueprints/svg.d.ts +0 -1
- package/dist/2d/curve2dGeometryFns.d.ts +0 -1
- package/dist/2d/curves.d.ts +0 -1
- package/dist/2d/lib/approximations.d.ts +0 -1
- package/dist/2d/lib/boundingBox2d.d.ts +0 -1
- package/dist/2d/lib/curve2D.d.ts +0 -1
- package/dist/2d/lib/curve2dFns.d.ts +0 -1
- package/dist/2d/lib/customCorners.d.ts +0 -1
- package/dist/2d/lib/definitions.d.ts +0 -1
- package/dist/2d/lib/index.d.ts +0 -1
- package/dist/2d/lib/intersections.d.ts +0 -1
- package/dist/2d/lib/makeCurves.d.ts +0 -1
- package/dist/2d/lib/offset.d.ts +0 -1
- package/dist/2d/lib/precision.d.ts +0 -1
- package/dist/2d/lib/stitching.d.ts +0 -1
- package/dist/2d/lib/svgPath.d.ts +0 -1
- package/dist/2d/lib/utils.d.ts +0 -1
- package/dist/2d/lib/vectorOperations.d.ts +0 -1
- package/dist/2d.cjs +19 -18
- package/dist/2d.d.ts +0 -1
- package/dist/2d.js +6 -5
- package/dist/{blueprint-C5LxqHCa.cjs → blueprint-B8ogGJiQ.cjs} +6 -6
- package/dist/{blueprint-CBairprN.js → blueprint-Dv45Evnu.js} +6 -6
- package/dist/{blueprintFns-CwbDuLxf.cjs → blueprintFns-BK3FYYjO.cjs} +3 -3
- package/dist/{blueprintFns-D8ST0Cf4.js → blueprintFns-a9C2g8_E.js} +2 -2
- package/dist/{boolean2D-DxZ3Kwlq.cjs → blueprintSketcher-Bei866Bt.cjs} +53 -1373
- package/dist/{boolean2D-A5u9tJYl.js → blueprintSketcher-xDsl9GXO.js} +59 -1307
- package/dist/boolean2D-DGuiEJHA.cjs +902 -0
- package/dist/boolean2D-Z7P0c012.js +855 -0
- package/dist/{booleanFns-DjZF4MJ5.js → booleanFns-CRa80qMX.js} +5 -5
- package/dist/{booleanFns-DWQMtFDN.cjs → booleanFns-qmgMQyDl.cjs} +8 -8
- package/dist/brepjs.cjs +742 -92
- package/dist/brepjs.js +662 -22
- package/dist/cameraFns-1y1NyACI.cjs +315 -0
- package/dist/cameraFns-CUzI5RKS.js +274 -0
- package/dist/core/constants.d.ts +0 -1
- package/dist/core/curve2dHandle.d.ts +0 -1
- package/dist/core/dimensionTypes.d.ts +0 -1
- package/dist/core/disposal.d.ts +0 -1
- package/dist/core/errors.d.ts +0 -1
- package/dist/core/kernelBoundary.d.ts +0 -1
- package/dist/core/kernelCall.d.ts +0 -1
- package/dist/core/kernelErrorTranslation.d.ts +0 -1
- package/dist/core/planeOps.d.ts +0 -1
- package/dist/core/planeTypes.d.ts +0 -1
- package/dist/core/result.d.ts +0 -1
- package/dist/core/shapeTypeCache.d.ts +0 -1
- package/dist/core/shapeTypes.d.ts +0 -1
- package/dist/core/typeDiscriminants.d.ts +0 -1
- package/dist/core/types.d.ts +0 -1
- package/dist/core/validityTypes.d.ts +0 -1
- package/dist/core/vecOps.d.ts +0 -1
- package/dist/core.cjs +1 -1
- package/dist/core.d.ts +0 -1
- package/dist/core.js +1 -1
- package/dist/{cornerFinder-B2CpcVV9.cjs → cornerFinder-CC8EBRCR.cjs} +2 -2
- package/dist/{cornerFinder-DGvOt2ab.js → cornerFinder-Dix2ghke.js} +2 -2
- package/dist/{curveFns-DZYE3BGO.js → curveFns-B4tWuinR.js} +1 -1
- package/dist/{curveFns-B8KJKr8-.cjs → curveFns-CD20-4fM.cjs} +1 -1
- package/dist/{drawFns-Bl865kUL.js → drawFns-BsarLfUN.js} +155 -762
- package/dist/{drawFns-h8gJBx-H.cjs → drawFns-LlOZoFyp.cjs} +193 -976
- package/dist/{extrudeFns-O2s-SFf-.js → extrudeFns-7pE8dIWz.js} +1 -1
- package/dist/{extrudeFns-BlJKAnW8.cjs → extrudeFns-DD36mWKv.cjs} +1 -1
- package/dist/faceFns-BFWz17_E.js +218 -0
- package/dist/faceFns-DP7i60yJ.cjs +343 -0
- package/dist/gear/gearFns.d.ts +129 -0
- package/dist/gear/gearMath.d.ts +88 -0
- package/dist/gear/gearProfile.d.ts +16 -0
- package/dist/gear/index.d.ts +3 -0
- package/dist/{helpers-C3smxDtp.cjs → helpers-Cyj6gaqy.cjs} +11 -10
- package/dist/{helpers-DL1f3xp0.js → helpers-vV2ONZwD.js} +6 -5
- package/dist/{historyFns-CD9qXw5j.js → historyFns-DGb61ETW.js} +4 -4
- package/dist/{historyFns-DBdWeo7Y.cjs → historyFns-DfyrPjnK.cjs} +4 -4
- package/dist/{importFns-5tcN3-fK.cjs → importFns-C-p0vl_h.cjs} +3 -3
- package/dist/{importFns-B1p3FiGS.js → importFns-Ci-L2iB3.js} +3 -3
- package/dist/index.d.ts +16 -8
- package/dist/io/dxfExportFns.d.ts +0 -1
- package/dist/io/dxfImportFns.d.ts +0 -1
- package/dist/io/gltfExportFns.d.ts +0 -1
- package/dist/io/gltfImportFns.d.ts +0 -1
- package/dist/io/importFns.d.ts +0 -1
- package/dist/io/ioUtils.d.ts +0 -1
- package/dist/io/objExportFns.d.ts +0 -1
- package/dist/io/objImportFns.d.ts +0 -1
- package/dist/io/stepConfigFns.d.ts +0 -1
- package/dist/io/svgImportFns.d.ts +0 -1
- package/dist/io/threemfExportFns.d.ts +0 -1
- package/dist/io/threemfImportFns.d.ts +0 -1
- package/dist/io.cjs +2 -2
- package/dist/io.d.ts +0 -1
- package/dist/io.js +2 -2
- package/dist/kernel/brepkit/booleanOps.d.ts +23 -1
- package/dist/kernel/brepkit/brepkitAdapter.d.ts +21 -408
- package/dist/kernel/brepkit/brepkitWasmTypes.d.ts +0 -1
- package/dist/kernel/brepkit/constructionOps.d.ts +51 -1
- package/dist/kernel/brepkit/evolutionOps.d.ts +34 -3
- package/dist/kernel/brepkit/geometryOps.d.ts +63 -2
- package/dist/kernel/brepkit/helpers.d.ts +6 -1
- package/dist/kernel/brepkit/internalOps.d.ts +0 -1
- package/dist/kernel/brepkit/ioOps.d.ts +47 -9
- package/dist/kernel/brepkit/kernel2dOps.d.ts +113 -1
- package/dist/kernel/brepkit/measureOps.d.ts +39 -1
- package/dist/kernel/brepkit/meshOps.d.ts +7 -1
- package/dist/kernel/brepkit/modifierOps.d.ts +15 -1
- package/dist/kernel/brepkit/repairOps.d.ts +14 -1
- package/dist/kernel/brepkit/sketchOps.d.ts +3 -1
- package/dist/kernel/brepkit/sweepOps.d.ts +37 -1
- package/dist/kernel/brepkit/topologyOps.d.ts +16 -1
- package/dist/kernel/brepkit/transformOps.d.ts +18 -1
- package/dist/kernel/geometry2d.d.ts +0 -1
- package/dist/kernel/index.d.ts +0 -1
- package/dist/kernel/interfaces/booleanOps.d.ts +0 -1
- package/dist/kernel/interfaces/builderOps.d.ts +0 -1
- package/dist/kernel/interfaces/core.d.ts +0 -1
- package/dist/kernel/interfaces/curveOps.d.ts +0 -1
- package/dist/kernel/interfaces/evolutionOps.d.ts +0 -1
- package/dist/kernel/interfaces/index.d.ts +0 -1
- package/dist/kernel/interfaces/ioOps.d.ts +0 -1
- package/dist/kernel/interfaces/measureOps.d.ts +0 -1
- package/dist/kernel/interfaces/meshOps.d.ts +0 -1
- package/dist/kernel/interfaces/modifierOps.d.ts +0 -1
- package/dist/kernel/interfaces/primitiveOps.d.ts +0 -1
- package/dist/kernel/interfaces/repairOps.d.ts +0 -1
- package/dist/kernel/interfaces/surfaceOps.d.ts +0 -1
- package/dist/kernel/interfaces/sweepOps.d.ts +0 -1
- package/dist/kernel/interfaces/topologyOps.d.ts +0 -1
- package/dist/kernel/interfaces/transformOps.d.ts +0 -1
- package/dist/kernel/kernel2dTypes.d.ts +0 -1
- package/dist/kernel/occt/advancedOps.d.ts +126 -24
- package/dist/kernel/occt/booleanBatchOps.d.ts +0 -1
- package/dist/kernel/occt/booleanOps.d.ts +11 -1
- package/dist/kernel/occt/booleanPipelineOps.d.ts +10 -1
- package/dist/kernel/occt/constructorOps.d.ts +14 -1
- package/dist/kernel/occt/curveOps.d.ts +13 -1
- package/dist/kernel/occt/defaultAdapter.d.ts +10 -441
- package/dist/kernel/occt/evolutionOps.d.ts +0 -1
- package/dist/kernel/occt/extendedConstructorOps.d.ts +31 -1
- package/dist/kernel/occt/geometryQueryOps.d.ts +40 -1
- package/dist/kernel/occt/healingOps.d.ts +6 -1
- package/dist/kernel/occt/historyOps.d.ts +17 -1
- package/dist/kernel/occt/hullOps.d.ts +14 -1
- package/dist/kernel/occt/ioOps.d.ts +9 -1
- package/dist/kernel/occt/kernel2dOps.d.ts +113 -1
- package/dist/kernel/occt/measureOps.d.ts +19 -1
- package/dist/kernel/occt/meshOps.d.ts +5 -1
- package/dist/kernel/occt/modifierOps.d.ts +24 -1
- package/dist/kernel/occt/nurbsQueryOps.d.ts +5 -1
- package/dist/kernel/occt/sweepOps.d.ts +23 -1
- package/dist/kernel/occt/topologyOps.d.ts +10 -1
- package/dist/kernel/occt/transformOps.d.ts +14 -4
- package/dist/kernel/occt/wasmTypes/externals.d.ts +0 -1
- package/dist/kernel/occt/wasmTypes/index.d.ts +0 -1
- package/dist/kernel/occt/wasmTypes/occtBuilders.d.ts +0 -1
- package/dist/kernel/occtWasm/adapterShims.d.ts +0 -1
- package/dist/kernel/occtWasm/booleanOps.d.ts +0 -1
- package/dist/kernel/occtWasm/constructionOps.d.ts +0 -1
- package/dist/kernel/occtWasm/curveOps.d.ts +0 -1
- package/dist/kernel/occtWasm/evolutionOps.d.ts +0 -1
- package/dist/kernel/occtWasm/helpers.d.ts +0 -1
- package/dist/kernel/occtWasm/hullOps.d.ts +0 -1
- package/dist/kernel/occtWasm/ioOps.d.ts +0 -1
- package/dist/kernel/occtWasm/kernel2dOps.d.ts +0 -1
- package/dist/kernel/occtWasm/measureOps.d.ts +0 -1
- package/dist/kernel/occtWasm/meshOps.d.ts +0 -1
- package/dist/kernel/occtWasm/modifierOps.d.ts +0 -1
- package/dist/kernel/occtWasm/occtWasmAdapter.d.ts +0 -1
- package/dist/kernel/occtWasm/occtWasmTypes.d.ts +0 -1
- package/dist/kernel/occtWasm/primitiveOps.d.ts +0 -1
- package/dist/kernel/occtWasm/repairOps.d.ts +0 -1
- package/dist/kernel/occtWasm/surfaceOps.d.ts +0 -1
- package/dist/kernel/occtWasm/sweepOps.d.ts +0 -1
- package/dist/kernel/occtWasm/topologyOps.d.ts +0 -1
- package/dist/kernel/occtWasm/transformOps.d.ts +0 -1
- package/dist/kernel/perfStats.d.ts +0 -1
- package/dist/kernel/solverAdapter.d.ts +0 -1
- package/dist/kernel/types.d.ts +0 -1
- package/dist/{measureFns-CHmy_Inq.cjs → measureFns-6ifSQfJt.cjs} +5 -4
- package/dist/{measureFns-CJi8erDL.js → measureFns-Io2nHE1k.js} +3 -2
- package/dist/measurement/interferenceFns.d.ts +0 -1
- package/dist/measurement/measureCache.d.ts +0 -1
- package/dist/measurement/measureFns.d.ts +0 -1
- package/dist/measurement/measureTypes.d.ts +0 -1
- package/dist/measurement.cjs +1 -1
- package/dist/measurement.d.ts +0 -1
- package/dist/measurement.js +1 -1
- package/dist/{meshFns-t2lR4BDS.cjs → meshFns-BCRVZgPi.cjs} +2 -2
- package/dist/{meshFns-BkY1RAoC.js → meshFns-DSdkRFWq.js} +2 -2
- package/dist/ns/booleans.d.ts +0 -1
- package/dist/ns/construction.d.ts +0 -1
- package/dist/ns/ioNs.d.ts +0 -1
- package/dist/ns/measurement.d.ts +0 -1
- package/dist/ns/modifiers.d.ts +0 -1
- package/dist/ns/patterns.d.ts +0 -1
- package/dist/ns/primitives.d.ts +0 -1
- package/dist/ns/query.d.ts +0 -1
- package/dist/ns/transforms.d.ts +0 -1
- package/dist/operations/api.d.ts +0 -1
- package/dist/operations/assemblyFns.d.ts +0 -1
- package/dist/operations/compoundOpsFns.d.ts +0 -1
- package/dist/operations/convexHullFns.d.ts +0 -1
- package/dist/operations/exporterFns.d.ts +0 -1
- package/dist/operations/exporterUtils.d.ts +0 -1
- package/dist/operations/exporters.d.ts +0 -1
- package/dist/operations/extrudeFns.d.ts +0 -1
- package/dist/operations/extrudeUtils.d.ts +0 -1
- package/dist/operations/guidedSweepFns.d.ts +0 -1
- package/dist/operations/historyFns.d.ts +0 -1
- package/dist/operations/loftFns.d.ts +0 -1
- package/dist/operations/mateFns.d.ts +0 -1
- package/dist/operations/multiSweepFns.d.ts +0 -1
- package/dist/operations/patternFns.d.ts +0 -1
- package/dist/operations/roofFns.d.ts +0 -1
- package/dist/operations/straightSkeleton.d.ts +0 -1
- package/dist/operations/sweepFns.d.ts +0 -1
- package/dist/operations.cjs +2 -2
- package/dist/operations.d.ts +0 -1
- package/dist/operations.js +2 -2
- package/dist/{primitiveFns-DwhN--zB.cjs → primitiveFns-BH-JQPzh.cjs} +18 -17
- package/dist/{primitiveFns-Emvge_71.js → primitiveFns-C1p92ZcD.js} +6 -5
- package/dist/projection/cameraFns.d.ts +0 -1
- package/dist/projection/makeProjectedEdges.d.ts +0 -1
- package/dist/projection/projectionPlanes.d.ts +0 -1
- package/dist/projection.cjs +9 -0
- package/dist/projection.d.ts +11 -0
- package/dist/projection.js +2 -0
- package/dist/query/cornerFinder.d.ts +0 -1
- package/dist/query/directionUtils.d.ts +0 -1
- package/dist/query/edgeFinder.d.ts +0 -1
- package/dist/query/faceFinder.d.ts +0 -1
- package/dist/query/finderCore.d.ts +0 -1
- package/dist/query/finderFns.d.ts +0 -1
- package/dist/query/helpers.d.ts +0 -1
- package/dist/query/shapeDistanceFilter.d.ts +0 -1
- package/dist/query/shapeFinders.d.ts +0 -1
- package/dist/query/vertexFinder.d.ts +0 -1
- package/dist/query/wireFinder.d.ts +0 -1
- package/dist/query.cjs +2 -2
- package/dist/query.d.ts +0 -1
- package/dist/query.js +2 -2
- package/dist/result.d.ts +0 -1
- package/dist/{shapeFns-CObBAJoQ.cjs → shapeFns-B7x82K11.cjs} +15 -15
- package/dist/{shapeFns-DThjHtJI.js → shapeFns-BhZ9weSI.js} +2 -2
- package/dist/shapeRef.cjs +1 -1
- package/dist/shapeRef.d.ts +0 -1
- package/dist/shapeRef.js +1 -1
- package/dist/{shapeRefFns-WMhIFuGW.js → shapeRefFns-B9PsEqWf.js} +4 -3
- package/dist/{shapeRefFns-I0MHjRAq.cjs → shapeRefFns-wDY88A8u.cjs} +6 -5
- package/dist/{shapeTypes-8vB31RfA.cjs → shapeTypes-BTt_LLbk.cjs} +6928 -7750
- package/dist/{shapeTypes-AyL8vv_O.js → shapeTypes-C--1jaT1.js} +6618 -7440
- package/dist/sketching/cannedSketches.d.ts +0 -1
- package/dist/sketching/compoundSketch.d.ts +8 -7
- package/dist/sketching/draw3d.d.ts +1 -2
- package/dist/sketching/drawFns.d.ts +4 -3
- package/dist/sketching/{draw.d.ts → drawing.d.ts} +2 -127
- package/dist/sketching/drawingFactories.d.ts +94 -0
- package/dist/sketching/drawingPen.d.ts +34 -0
- package/dist/sketching/faceSketcher.d.ts +52 -0
- package/dist/sketching/shortcuts.d.ts +0 -1
- package/dist/sketching/sketch.d.ts +64 -10
- package/dist/sketching/sketchFns.d.ts +42 -95
- package/dist/sketching/sketcher.d.ts +2 -3
- package/dist/sketching/sketches.d.ts +5 -6
- package/dist/sketching.cjs +19 -18
- package/dist/sketching.d.ts +8 -5
- package/dist/sketching.js +3 -2
- package/dist/{solidBuilders-Djwgx2mj.cjs → solidBuilders-CX_197Xm.cjs} +2 -2
- package/dist/{solidBuilders-C7Xp_ikW.js → solidBuilders-Xs7VDMGD.js} +2 -2
- package/dist/{surfaceBuilders-BEnsewN9.cjs → surfaceBuilders-CYeTNW33.cjs} +24 -2
- package/dist/{surfaceBuilders-Con0IpLf.js → surfaceBuilders-CinmHCbZ.js} +19 -3
- package/dist/text/fontRegistry.d.ts +22 -0
- package/dist/text/sketchText.d.ts +30 -0
- package/dist/text/textBlueprints.d.ts +0 -91
- package/dist/text/textMetrics.d.ts +39 -0
- package/dist/text.cjs +9 -0
- package/dist/text.d.ts +12 -0
- package/dist/text.js +3 -0
- package/dist/textBlueprints-Do6xNsLt.js +643 -0
- package/dist/textBlueprints-oWhiABaY.cjs +800 -0
- package/dist/textMetrics-BjJ8sn_e.js +69 -0
- package/dist/textMetrics-CUvtglQE.cjs +86 -0
- package/dist/topology/adjacencyFns.d.ts +0 -1
- package/dist/topology/api.d.ts +0 -1
- package/dist/topology/apiTypes.d.ts +0 -1
- package/dist/topology/booleanDiagnosticFns.d.ts +0 -1
- package/dist/topology/booleanFns.d.ts +0 -1
- package/dist/topology/cast.d.ts +0 -1
- package/dist/topology/chamferAngleFns.d.ts +0 -1
- package/dist/topology/compoundOpsFns.d.ts +0 -1
- package/dist/topology/curveBuilders.d.ts +12 -1
- package/dist/topology/curveFns.d.ts +0 -1
- package/dist/topology/evolutionFns.d.ts +0 -1
- package/dist/topology/faceFns.d.ts +0 -1
- package/dist/topology/healingFns.d.ts +0 -1
- package/dist/topology/hullFns.d.ts +0 -1
- package/dist/topology/index.d.ts +0 -1
- package/dist/topology/meshCache.d.ts +0 -1
- package/dist/topology/meshFns.d.ts +0 -1
- package/dist/topology/metadata/colorFns.d.ts +0 -1
- package/dist/topology/metadata/faceTagFns.d.ts +0 -1
- package/dist/topology/metadata/metadataPropagation.d.ts +0 -1
- package/dist/topology/metadata/originTrackingFns.d.ts +0 -1
- package/dist/topology/minkowskiFns.d.ts +0 -1
- package/dist/topology/modifierFns.d.ts +0 -1
- package/dist/topology/nurbsFns.d.ts +0 -1
- package/dist/topology/polyhedronFns.d.ts +0 -1
- package/dist/topology/positionFns.d.ts +0 -1
- package/dist/topology/primitiveFns.d.ts +0 -1
- package/dist/topology/shapeBooleans.d.ts +0 -1
- package/dist/topology/shapeFns.d.ts +0 -1
- package/dist/topology/shapeHelpers.d.ts +0 -1
- package/dist/topology/shapeModifiers.d.ts +0 -1
- package/dist/topology/shapeRef/index.d.ts +0 -1
- package/dist/topology/shapeRef/scoring.d.ts +0 -1
- package/dist/topology/shapeRef/shapeRefFns.d.ts +0 -1
- package/dist/topology/shapeRef/shapeRefTypes.d.ts +0 -1
- package/dist/topology/shapeUtils.d.ts +0 -1
- package/dist/topology/solidBuilders.d.ts +0 -1
- package/dist/topology/surfaceBuilders.d.ts +0 -1
- package/dist/topology/surfaceFns.d.ts +0 -1
- package/dist/topology/threeHelpers.d.ts +0 -1
- package/dist/topology/topologyQueryFns.d.ts +0 -1
- package/dist/topology/transformFns.d.ts +0 -1
- package/dist/topology/wrapperFns.d.ts +0 -1
- package/dist/topology.cjs +18 -17
- package/dist/topology.d.ts +0 -1
- package/dist/topology.js +7 -6
- package/dist/{faceFns-B1H43mZ_.cjs → topologyQueryFns-BU0qdNJP.cjs} +1 -341
- package/dist/{faceFns-acz86gqR.js → topologyQueryFns-Dhf85ZBK.js} +3 -217
- package/dist/utils/arrayAccess.d.ts +0 -1
- package/dist/utils/bug.d.ts +0 -1
- package/dist/utils/ioFilename.d.ts +0 -1
- package/dist/utils/precisionRound.d.ts +0 -1
- package/dist/utils/range.d.ts +0 -1
- package/dist/utils/uuid.d.ts +0 -1
- package/dist/utils/vec2d.d.ts +0 -1
- package/dist/utils/vec3.d.ts +0 -1
- package/dist/utils/zip.d.ts +0 -1
- package/dist/vectors.d.ts +0 -1
- package/dist/worker/index.d.ts +0 -1
- package/dist/worker/protocol.d.ts +0 -1
- package/dist/worker/taskQueue.d.ts +0 -1
- package/dist/worker/workerClient.d.ts +0 -1
- package/dist/worker/workerHandler.d.ts +0 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.d.ts +0 -1
- package/dist/worker.js +1 -1
- package/package.json +35 -14
- package/dist/2d/blueprints/blueprint.d.ts.map +0 -1
- package/dist/2d/blueprints/blueprintApproximations.d.ts.map +0 -1
- package/dist/2d/blueprints/blueprintCustomCorners.d.ts.map +0 -1
- package/dist/2d/blueprints/blueprintFns.d.ts.map +0 -1
- package/dist/2d/blueprints/blueprintOffset.d.ts.map +0 -1
- package/dist/2d/blueprints/blueprints.d.ts.map +0 -1
- package/dist/2d/blueprints/boolean2D.d.ts.map +0 -1
- package/dist/2d/blueprints/booleanHelpers.d.ts.map +0 -1
- package/dist/2d/blueprints/booleanOperations.d.ts.map +0 -1
- package/dist/2d/blueprints/cannedBlueprints.d.ts.map +0 -1
- package/dist/2d/blueprints/compoundBlueprint.d.ts.map +0 -1
- package/dist/2d/blueprints/index.d.ts.map +0 -1
- package/dist/2d/blueprints/intersectionSegments.d.ts.map +0 -1
- package/dist/2d/blueprints/lib.d.ts.map +0 -1
- package/dist/2d/blueprints/segmentAssembly.d.ts.map +0 -1
- package/dist/2d/blueprints/svg.d.ts.map +0 -1
- package/dist/2d/curve2dGeometryFns.d.ts.map +0 -1
- package/dist/2d/curves.d.ts.map +0 -1
- package/dist/2d/lib/approximations.d.ts.map +0 -1
- package/dist/2d/lib/boundingBox2d.d.ts.map +0 -1
- package/dist/2d/lib/curve2D.d.ts.map +0 -1
- package/dist/2d/lib/curve2dFns.d.ts.map +0 -1
- package/dist/2d/lib/customCorners.d.ts.map +0 -1
- package/dist/2d/lib/definitions.d.ts.map +0 -1
- package/dist/2d/lib/index.d.ts.map +0 -1
- package/dist/2d/lib/intersections.d.ts.map +0 -1
- package/dist/2d/lib/makeCurves.d.ts.map +0 -1
- package/dist/2d/lib/offset.d.ts.map +0 -1
- package/dist/2d/lib/precision.d.ts.map +0 -1
- package/dist/2d/lib/stitching.d.ts.map +0 -1
- package/dist/2d/lib/svgPath.d.ts.map +0 -1
- package/dist/2d/lib/utils.d.ts.map +0 -1
- package/dist/2d/lib/vectorOperations.d.ts.map +0 -1
- package/dist/2d.d.ts.map +0 -1
- package/dist/core/constants.d.ts.map +0 -1
- package/dist/core/curve2dHandle.d.ts.map +0 -1
- package/dist/core/dimensionTypes.d.ts.map +0 -1
- package/dist/core/disposal.d.ts.map +0 -1
- package/dist/core/errors.d.ts.map +0 -1
- package/dist/core/kernelBoundary.d.ts.map +0 -1
- package/dist/core/kernelCall.d.ts.map +0 -1
- package/dist/core/kernelErrorTranslation.d.ts.map +0 -1
- package/dist/core/planeOps.d.ts.map +0 -1
- package/dist/core/planeTypes.d.ts.map +0 -1
- package/dist/core/result.d.ts.map +0 -1
- package/dist/core/shapeTypeCache.d.ts.map +0 -1
- package/dist/core/shapeTypes.d.ts.map +0 -1
- package/dist/core/typeDiscriminants.d.ts.map +0 -1
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/validityTypes.d.ts.map +0 -1
- package/dist/core/vecOps.d.ts.map +0 -1
- package/dist/core.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/io/dxfExportFns.d.ts.map +0 -1
- package/dist/io/dxfImportFns.d.ts.map +0 -1
- package/dist/io/gltfExportFns.d.ts.map +0 -1
- package/dist/io/gltfImportFns.d.ts.map +0 -1
- package/dist/io/importFns.d.ts.map +0 -1
- package/dist/io/ioUtils.d.ts.map +0 -1
- package/dist/io/objExportFns.d.ts.map +0 -1
- package/dist/io/objImportFns.d.ts.map +0 -1
- package/dist/io/stepConfigFns.d.ts.map +0 -1
- package/dist/io/svgImportFns.d.ts.map +0 -1
- package/dist/io/threemfExportFns.d.ts.map +0 -1
- package/dist/io/threemfImportFns.d.ts.map +0 -1
- package/dist/io.d.ts.map +0 -1
- package/dist/kernel/brepkit/booleanOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/brepkitAdapter.d.ts.map +0 -1
- package/dist/kernel/brepkit/brepkitWasmTypes.d.ts.map +0 -1
- package/dist/kernel/brepkit/constructionOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/evolutionOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/geometryOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/helpers.d.ts.map +0 -1
- package/dist/kernel/brepkit/internalOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/ioOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/kernel2dOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/measureOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/meshOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/modifierOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/repairOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/sketchOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/sweepOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/topologyOps.d.ts.map +0 -1
- package/dist/kernel/brepkit/transformOps.d.ts.map +0 -1
- package/dist/kernel/geometry2d.d.ts.map +0 -1
- package/dist/kernel/index.d.ts.map +0 -1
- package/dist/kernel/interfaces/booleanOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/builderOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/core.d.ts.map +0 -1
- package/dist/kernel/interfaces/curveOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/evolutionOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/index.d.ts.map +0 -1
- package/dist/kernel/interfaces/ioOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/measureOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/meshOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/modifierOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/primitiveOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/repairOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/surfaceOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/sweepOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/topologyOps.d.ts.map +0 -1
- package/dist/kernel/interfaces/transformOps.d.ts.map +0 -1
- package/dist/kernel/kernel2dTypes.d.ts.map +0 -1
- package/dist/kernel/occt/advancedOps.d.ts.map +0 -1
- package/dist/kernel/occt/booleanBatchOps.d.ts.map +0 -1
- package/dist/kernel/occt/booleanOps.d.ts.map +0 -1
- package/dist/kernel/occt/booleanPipelineOps.d.ts.map +0 -1
- package/dist/kernel/occt/constructorOps.d.ts.map +0 -1
- package/dist/kernel/occt/curveOps.d.ts.map +0 -1
- package/dist/kernel/occt/defaultAdapter.d.ts.map +0 -1
- package/dist/kernel/occt/evolutionOps.d.ts.map +0 -1
- package/dist/kernel/occt/extendedConstructorOps.d.ts.map +0 -1
- package/dist/kernel/occt/geometryQueryOps.d.ts.map +0 -1
- package/dist/kernel/occt/healingOps.d.ts.map +0 -1
- package/dist/kernel/occt/historyOps.d.ts.map +0 -1
- package/dist/kernel/occt/hullOps.d.ts.map +0 -1
- package/dist/kernel/occt/ioOps.d.ts.map +0 -1
- package/dist/kernel/occt/kernel2dOps.d.ts.map +0 -1
- package/dist/kernel/occt/measureOps.d.ts.map +0 -1
- package/dist/kernel/occt/meshOps.d.ts.map +0 -1
- package/dist/kernel/occt/modifierOps.d.ts.map +0 -1
- package/dist/kernel/occt/nurbsQueryOps.d.ts.map +0 -1
- package/dist/kernel/occt/sweepOps.d.ts.map +0 -1
- package/dist/kernel/occt/topologyOps.d.ts.map +0 -1
- package/dist/kernel/occt/transformOps.d.ts.map +0 -1
- package/dist/kernel/occt/wasmTypes/externals.d.ts.map +0 -1
- package/dist/kernel/occt/wasmTypes/index.d.ts.map +0 -1
- package/dist/kernel/occt/wasmTypes/occtBuilders.d.ts.map +0 -1
- package/dist/kernel/occtWasm/adapterShims.d.ts.map +0 -1
- package/dist/kernel/occtWasm/booleanOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/constructionOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/curveOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/evolutionOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/helpers.d.ts.map +0 -1
- package/dist/kernel/occtWasm/hullOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/ioOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/kernel2dOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/measureOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/meshOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/modifierOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/occtWasmAdapter.d.ts.map +0 -1
- package/dist/kernel/occtWasm/occtWasmTypes.d.ts.map +0 -1
- package/dist/kernel/occtWasm/primitiveOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/repairOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/surfaceOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/sweepOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/topologyOps.d.ts.map +0 -1
- package/dist/kernel/occtWasm/transformOps.d.ts.map +0 -1
- package/dist/kernel/perfStats.d.ts.map +0 -1
- package/dist/kernel/solverAdapter.d.ts.map +0 -1
- package/dist/kernel/types.d.ts.map +0 -1
- package/dist/measurement/interferenceFns.d.ts.map +0 -1
- package/dist/measurement/measureCache.d.ts.map +0 -1
- package/dist/measurement/measureFns.d.ts.map +0 -1
- package/dist/measurement/measureTypes.d.ts.map +0 -1
- package/dist/measurement.d.ts.map +0 -1
- package/dist/ns/booleans.d.ts.map +0 -1
- package/dist/ns/construction.d.ts.map +0 -1
- package/dist/ns/ioNs.d.ts.map +0 -1
- package/dist/ns/measurement.d.ts.map +0 -1
- package/dist/ns/modifiers.d.ts.map +0 -1
- package/dist/ns/patterns.d.ts.map +0 -1
- package/dist/ns/primitives.d.ts.map +0 -1
- package/dist/ns/query.d.ts.map +0 -1
- package/dist/ns/transforms.d.ts.map +0 -1
- package/dist/operations/api.d.ts.map +0 -1
- package/dist/operations/assemblyFns.d.ts.map +0 -1
- package/dist/operations/compoundOpsFns.d.ts.map +0 -1
- package/dist/operations/convexHullFns.d.ts.map +0 -1
- package/dist/operations/exporterFns.d.ts.map +0 -1
- package/dist/operations/exporterUtils.d.ts.map +0 -1
- package/dist/operations/exporters.d.ts.map +0 -1
- package/dist/operations/extrudeFns.d.ts.map +0 -1
- package/dist/operations/extrudeUtils.d.ts.map +0 -1
- package/dist/operations/guidedSweepFns.d.ts.map +0 -1
- package/dist/operations/historyFns.d.ts.map +0 -1
- package/dist/operations/loftFns.d.ts.map +0 -1
- package/dist/operations/mateFns.d.ts.map +0 -1
- package/dist/operations/multiSweepFns.d.ts.map +0 -1
- package/dist/operations/patternFns.d.ts.map +0 -1
- package/dist/operations/roofFns.d.ts.map +0 -1
- package/dist/operations/straightSkeleton.d.ts.map +0 -1
- package/dist/operations/sweepFns.d.ts.map +0 -1
- package/dist/operations.d.ts.map +0 -1
- package/dist/projection/cameraFns.d.ts.map +0 -1
- package/dist/projection/makeProjectedEdges.d.ts.map +0 -1
- package/dist/projection/projectionPlanes.d.ts.map +0 -1
- package/dist/query/cornerFinder.d.ts.map +0 -1
- package/dist/query/directionUtils.d.ts.map +0 -1
- package/dist/query/edgeFinder.d.ts.map +0 -1
- package/dist/query/faceFinder.d.ts.map +0 -1
- package/dist/query/finderCore.d.ts.map +0 -1
- package/dist/query/finderFns.d.ts.map +0 -1
- package/dist/query/helpers.d.ts.map +0 -1
- package/dist/query/shapeDistanceFilter.d.ts.map +0 -1
- package/dist/query/shapeFinders.d.ts.map +0 -1
- package/dist/query/vertexFinder.d.ts.map +0 -1
- package/dist/query/wireFinder.d.ts.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/quick.d.ts.map +0 -1
- package/dist/result.d.ts.map +0 -1
- package/dist/shapeRef.d.ts.map +0 -1
- package/dist/sketching/cannedSketches.d.ts.map +0 -1
- package/dist/sketching/compoundSketch.d.ts.map +0 -1
- package/dist/sketching/draw.d.ts.map +0 -1
- package/dist/sketching/draw3d.d.ts.map +0 -1
- package/dist/sketching/drawFns.d.ts.map +0 -1
- package/dist/sketching/ellipseUtils.d.ts.map +0 -1
- package/dist/sketching/shortcuts.d.ts.map +0 -1
- package/dist/sketching/sketch.d.ts.map +0 -1
- package/dist/sketching/sketchFns.d.ts.map +0 -1
- package/dist/sketching/sketchLib.d.ts +0 -47
- package/dist/sketching/sketchLib.d.ts.map +0 -1
- package/dist/sketching/sketchUtils.d.ts +0 -8
- package/dist/sketching/sketchUtils.d.ts.map +0 -1
- package/dist/sketching/sketcher.d.ts.map +0 -1
- package/dist/sketching/sketcher2d.d.ts.map +0 -1
- package/dist/sketching/sketcherlib.d.ts.map +0 -1
- package/dist/sketching/sketches.d.ts.map +0 -1
- package/dist/sketching.d.ts.map +0 -1
- package/dist/text/textBlueprints.d.ts.map +0 -1
- package/dist/topology/adjacencyFns.d.ts.map +0 -1
- package/dist/topology/api.d.ts.map +0 -1
- package/dist/topology/apiTypes.d.ts.map +0 -1
- package/dist/topology/booleanDiagnosticFns.d.ts.map +0 -1
- package/dist/topology/booleanFns.d.ts.map +0 -1
- package/dist/topology/cast.d.ts.map +0 -1
- package/dist/topology/chamferAngleFns.d.ts.map +0 -1
- package/dist/topology/compoundOpsFns.d.ts.map +0 -1
- package/dist/topology/curveBuilders.d.ts.map +0 -1
- package/dist/topology/curveFns.d.ts.map +0 -1
- package/dist/topology/evolutionFns.d.ts.map +0 -1
- package/dist/topology/faceFns.d.ts.map +0 -1
- package/dist/topology/healingFns.d.ts.map +0 -1
- package/dist/topology/hullFns.d.ts.map +0 -1
- package/dist/topology/index.d.ts.map +0 -1
- package/dist/topology/meshCache.d.ts.map +0 -1
- package/dist/topology/meshFns.d.ts.map +0 -1
- package/dist/topology/metadata/colorFns.d.ts.map +0 -1
- package/dist/topology/metadata/faceTagFns.d.ts.map +0 -1
- package/dist/topology/metadata/metadataPropagation.d.ts.map +0 -1
- package/dist/topology/metadata/originTrackingFns.d.ts.map +0 -1
- package/dist/topology/minkowskiFns.d.ts.map +0 -1
- package/dist/topology/modifierFns.d.ts.map +0 -1
- package/dist/topology/nurbsFns.d.ts.map +0 -1
- package/dist/topology/polyhedronFns.d.ts.map +0 -1
- package/dist/topology/positionFns.d.ts.map +0 -1
- package/dist/topology/primitiveFns.d.ts.map +0 -1
- package/dist/topology/shapeBooleans.d.ts.map +0 -1
- package/dist/topology/shapeFns.d.ts.map +0 -1
- package/dist/topology/shapeHelpers.d.ts.map +0 -1
- package/dist/topology/shapeModifiers.d.ts.map +0 -1
- package/dist/topology/shapeRef/index.d.ts.map +0 -1
- package/dist/topology/shapeRef/scoring.d.ts.map +0 -1
- package/dist/topology/shapeRef/shapeRefFns.d.ts.map +0 -1
- package/dist/topology/shapeRef/shapeRefTypes.d.ts.map +0 -1
- package/dist/topology/shapeUtils.d.ts.map +0 -1
- package/dist/topology/solidBuilders.d.ts.map +0 -1
- package/dist/topology/surfaceBuilders.d.ts.map +0 -1
- package/dist/topology/surfaceFns.d.ts.map +0 -1
- package/dist/topology/threeHelpers.d.ts.map +0 -1
- package/dist/topology/topologyQueryFns.d.ts.map +0 -1
- package/dist/topology/transformFns.d.ts.map +0 -1
- package/dist/topology/wrapperFns.d.ts.map +0 -1
- package/dist/topology.d.ts.map +0 -1
- package/dist/utils/arrayAccess.d.ts.map +0 -1
- package/dist/utils/bug.d.ts.map +0 -1
- package/dist/utils/ioFilename.d.ts.map +0 -1
- package/dist/utils/precisionRound.d.ts.map +0 -1
- package/dist/utils/range.d.ts.map +0 -1
- package/dist/utils/uuid.d.ts.map +0 -1
- package/dist/utils/vec2d.d.ts.map +0 -1
- package/dist/utils/vec3.d.ts.map +0 -1
- package/dist/utils/zip.d.ts.map +0 -1
- package/dist/vectors.d.ts.map +0 -1
- package/dist/worker/index.d.ts.map +0 -1
- package/dist/worker/protocol.d.ts.map +0 -1
- package/dist/worker/taskQueue.d.ts.map +0 -1
- package/dist/worker/workerClient.d.ts.map +0 -1
- package/dist/worker/workerHandler.d.ts.map +0 -1
- package/dist/worker.d.ts.map +0 -1
- /package/dist/{arrayAccess-Br-m2PP7.cjs → arrayAccess-7pTWqkJu.cjs} +0 -0
- /package/dist/{arrayAccess-2G0pRoaC.js → arrayAccess-C5IWcxs9.js} +0 -0
- /package/dist/{workerHandler-sCf818XJ.cjs → workerHandler-C7seK7H-.cjs} +0 -0
- /package/dist/{workerHandler-BndMJVx6.js → workerHandler-DaulgMax.js} +0 -0
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { X as getKernel, Z as getKernel2D } from "./shapeTypes-C--1jaT1.js";
|
|
2
2
|
import { n as wasmIndex } from "./vec3-BRj3eI54.js";
|
|
3
|
-
import { A as ok, R as unwrap, T as isOk, b as err,
|
|
4
|
-
import { N as downcast, c as normalAt, p as uvBounds, u as pointOnSurface } from "./faceFns-acz86gqR.js";
|
|
3
|
+
import { A as ok, R as unwrap, T as isOk, b as err, h as bug, n as computationError, s as safeIndex } from "./errors-0fYW_YnO.js";
|
|
5
4
|
import { r as RAD2DEG, t as DEG2RAD } from "./constants-Ci5CA3aZ.js";
|
|
6
|
-
import {
|
|
7
|
-
import { d as
|
|
8
|
-
import { n as
|
|
9
|
-
import { c as curveStartPoint, l as curveTangentAt, r as curveIsClosed } from "./curveFns-DZYE3BGO.js";
|
|
10
|
-
import { r as lastOrThrow, t as firstOrThrow } from "./arrayAccess-2G0pRoaC.js";
|
|
11
|
-
import { _ as zip, i as makeNewFaceWithinFace, r as makeFace, s as assembleWire } from "./surfaceBuilders-Con0IpLf.js";
|
|
12
|
-
import { _ as samePoint$1, b as subtract2d, d as cartesianToPolar, f as crossProduct2d, g as rotate2d, h as polarToCartesian, l as add2d, m as polarAngle2d, o as normalize2d, p as distance2d, s as PRECISION_INTERSECTION, v as scalarMultiply2d } from "./helpers-DL1f3xp0.js";
|
|
13
|
-
import { _ as Curve2D, b as removeDuplicatePoints, c as make2dCircle, f as make2dSegmentCurve, h as approximateAsBSpline, m as make2dThreePointArc, n as asSVG, o as make2dArcFromCenter, p as make2dTangentArc, r as viewbox, s as make2dBezierCurve, t as Blueprint, u as make2dEllipseArc, x as isPoint2D, y as BoundingBox2d } from "./blueprint-CBairprN.js";
|
|
14
|
-
import { c as sweep, i as complexExtrude, l as twistExtrude, r as revolve, t as extrude } from "./extrudeFns-O2s-SFf-.js";
|
|
5
|
+
import { t as firstOrThrow } from "./arrayAccess-C5IWcxs9.js";
|
|
6
|
+
import { _ as samePoint, b as subtract2d, d as cartesianToPolar, f as crossProduct2d, g as rotate2d, h as polarToCartesian, l as add2d, m as polarAngle2d, o as normalize2d, p as distance2d, v as scalarMultiply2d } from "./helpers-vV2ONZwD.js";
|
|
7
|
+
import { _ as Curve2D, c as make2dCircle, f as make2dSegmentCurve, h as approximateAsBSpline, m as make2dThreePointArc, n as asSVG, o as make2dArcFromCenter, p as make2dTangentArc, r as viewbox, s as make2dBezierCurve, t as Blueprint, u as make2dEllipseArc, x as isPoint2D, y as BoundingBox2d } from "./blueprint-Dv45Evnu.js";
|
|
15
8
|
//#region node_modules/flatqueue/index.js
|
|
16
9
|
/** @template T */
|
|
17
10
|
var FlatQueue = class {
|
|
@@ -493,10 +486,10 @@ var intersectCurves = (first, second, precision = 1e-9) => {
|
|
|
493
486
|
} catch (e) {
|
|
494
487
|
return err(computationError("INTERSECTION_FAILED", "Intersections failed between curves", e));
|
|
495
488
|
}
|
|
496
|
-
const segmentsAsPoints = commonSegments.filter((c) => samePoint
|
|
489
|
+
const segmentsAsPoints = commonSegments.filter((c) => samePoint(c.firstPoint, c.lastPoint, precision)).map((c) => c.firstPoint);
|
|
497
490
|
if (segmentsAsPoints.length) {
|
|
498
491
|
intersections.push(...segmentsAsPoints);
|
|
499
|
-
commonSegments = commonSegments.filter((c) => !samePoint
|
|
492
|
+
commonSegments = commonSegments.filter((c) => !samePoint(c.firstPoint, c.lastPoint, precision));
|
|
500
493
|
}
|
|
501
494
|
const commonSegmentsPoints = commonSegments.flatMap((c) => [c.firstPoint, c.lastPoint]);
|
|
502
495
|
return ok({
|
|
@@ -997,278 +990,7 @@ var organiseBlueprints = (blueprints) => {
|
|
|
997
990
|
}));
|
|
998
991
|
};
|
|
999
992
|
//#endregion
|
|
1000
|
-
//#region src/
|
|
1001
|
-
/**
|
|
1002
|
-
* Functional loft operation using branded shape types.
|
|
1003
|
-
*/
|
|
1004
|
-
/**
|
|
1005
|
-
* Loft through a set of wire profiles to create a 3D shape.
|
|
1006
|
-
*
|
|
1007
|
-
* Builds a `BRepOffsetAPI_ThruSections` surface through the given wires,
|
|
1008
|
-
* optionally starting and/or ending at point vertices. Produces a solid
|
|
1009
|
-
* by default, or a shell when `returnShell` is `true`.
|
|
1010
|
-
*
|
|
1011
|
-
* @param wires - Ordered wire profiles to loft through.
|
|
1012
|
-
* @param config - Loft configuration (ruled interpolation, start/end points).
|
|
1013
|
-
* @param returnShell - When `true`, return a shell instead of a solid.
|
|
1014
|
-
* @returns `Result` containing the lofted 3D shape, or an error on failure.
|
|
1015
|
-
*
|
|
1016
|
-
* @example
|
|
1017
|
-
* ```ts
|
|
1018
|
-
* const result = loft([bottomWire, topWire], { ruled: false });
|
|
1019
|
-
* ```
|
|
1020
|
-
*
|
|
1021
|
-
* @see {@link loft!loft | loft} for the OOP API equivalent.
|
|
1022
|
-
*/
|
|
1023
|
-
function loft(wires, { ruled = true, startPoint, endPoint, tolerance = 1e-6 } = {}, returnShell = false) {
|
|
1024
|
-
if (wires.length === 0 && !startPoint && !endPoint) return err(validationError("LOFT_EMPTY", "Loft requires at least one wire or start/end point"));
|
|
1025
|
-
const kernel = getKernel();
|
|
1026
|
-
const startVertex = startPoint ? kernel.makeVertex(...toVec3(startPoint)) : void 0;
|
|
1027
|
-
const endVertex = endPoint ? kernel.makeVertex(...toVec3(endPoint)) : void 0;
|
|
1028
|
-
try {
|
|
1029
|
-
const result = castShape(kernel.loftAdvanced(wires.map((w) => w.wrapped), {
|
|
1030
|
-
solid: !returnShell,
|
|
1031
|
-
ruled,
|
|
1032
|
-
tolerance,
|
|
1033
|
-
...startVertex ? { startVertex } : {},
|
|
1034
|
-
...endVertex ? { endVertex } : {}
|
|
1035
|
-
}));
|
|
1036
|
-
if (!isShape3D(result)) return err(typeCastError("LOFT_NOT_3D", "Loft did not produce a 3D shape"));
|
|
1037
|
-
return ok(result);
|
|
1038
|
-
} catch (e) {
|
|
1039
|
-
return err(kernelError("LOFT_FAILED", "Loft operation failed", e, void 0, "Common causes: wire profiles with different edge counts, self-intersecting result, or profiles too far apart. Ensure profiles are compatible and ordered."));
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
/**
|
|
1043
|
-
* Batch loft: build N independent lofts in a single kernel call.
|
|
1044
|
-
*
|
|
1045
|
-
* Uses the C++ LoftBatch extractor when available (single WASM call),
|
|
1046
|
-
* falling back to N individual loft operations otherwise.
|
|
1047
|
-
*
|
|
1048
|
-
* @returns Array of 3D shapes, one per entry.
|
|
1049
|
-
*/
|
|
1050
|
-
function loftAll(entries) {
|
|
1051
|
-
if (entries.length === 0) return ok([]);
|
|
1052
|
-
const kernel = getKernel();
|
|
1053
|
-
const verticesToDelete = [];
|
|
1054
|
-
const kernelEntries = entries.map((e) => {
|
|
1055
|
-
const startVertex = e.startPoint ? kernel.makeVertex(...toVec3(e.startPoint)) : void 0;
|
|
1056
|
-
const endVertex = e.endPoint ? kernel.makeVertex(...toVec3(e.endPoint)) : void 0;
|
|
1057
|
-
if (startVertex) verticesToDelete.push(startVertex);
|
|
1058
|
-
if (endVertex) verticesToDelete.push(endVertex);
|
|
1059
|
-
return {
|
|
1060
|
-
wires: e.wires.map((w) => w.wrapped),
|
|
1061
|
-
solid: true,
|
|
1062
|
-
ruled: e.ruled ?? true,
|
|
1063
|
-
tolerance: e.tolerance ?? 1e-6,
|
|
1064
|
-
startVertex,
|
|
1065
|
-
endVertex
|
|
1066
|
-
};
|
|
1067
|
-
});
|
|
1068
|
-
try {
|
|
1069
|
-
const shapes = kernel.loftBatch?.(kernelEntries) ?? kernelEntries.map((e) => kernel.loftAdvanced(e.wires, {
|
|
1070
|
-
solid: e.solid,
|
|
1071
|
-
ruled: e.ruled,
|
|
1072
|
-
tolerance: e.tolerance,
|
|
1073
|
-
startVertex: e.startVertex,
|
|
1074
|
-
endVertex: e.endVertex
|
|
1075
|
-
}));
|
|
1076
|
-
const results = [];
|
|
1077
|
-
for (const shape of shapes) {
|
|
1078
|
-
const cast = castShape(shape);
|
|
1079
|
-
if (!isShape3D(cast)) return err(typeCastError("LOFT_ALL_NOT_3D", "Batch loft entry did not produce a 3D shape"));
|
|
1080
|
-
results.push(cast);
|
|
1081
|
-
}
|
|
1082
|
-
return ok(results);
|
|
1083
|
-
} catch (e) {
|
|
1084
|
-
return err(kernelError("LOFT_ALL_FAILED", "Batch loft operation failed", e));
|
|
1085
|
-
} finally {
|
|
1086
|
-
for (const v of verticesToDelete) kernel.dispose(v);
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
//#endregion
|
|
1090
|
-
//#region src/sketching/sketch.ts
|
|
1091
|
-
/**
|
|
1092
|
-
* Represent a closed or open wire profile with a default extrusion origin and direction.
|
|
1093
|
-
*
|
|
1094
|
-
* A Sketch wraps a single {@link Wire} and carries metadata (origin, direction,
|
|
1095
|
-
* optional base face) so that downstream operations like {@link Sketch.extrude},
|
|
1096
|
-
* {@link Sketch.revolve}, {@link Sketch.sweepSketch}, and {@link Sketch.loftWith}
|
|
1097
|
-
* know how to act on it without extra arguments.
|
|
1098
|
-
*
|
|
1099
|
-
* @remarks Most operations consume (delete) the sketch after producing a solid.
|
|
1100
|
-
*
|
|
1101
|
-
* @see {@link Sketcher} to build a Sketch interactively.
|
|
1102
|
-
* @see {@link CompoundSketch} for multi-wire (outer + holes) profiles.
|
|
1103
|
-
* @category Sketching
|
|
1104
|
-
*/
|
|
1105
|
-
var Sketch = class Sketch {
|
|
1106
|
-
wire;
|
|
1107
|
-
/**
|
|
1108
|
-
* @ignore
|
|
1109
|
-
*/
|
|
1110
|
-
_defaultOrigin;
|
|
1111
|
-
/**
|
|
1112
|
-
* @ignore
|
|
1113
|
-
*/
|
|
1114
|
-
_defaultDirection;
|
|
1115
|
-
_baseFace;
|
|
1116
|
-
constructor(wire, { defaultOrigin = [
|
|
1117
|
-
0,
|
|
1118
|
-
0,
|
|
1119
|
-
0
|
|
1120
|
-
], defaultDirection = [
|
|
1121
|
-
0,
|
|
1122
|
-
0,
|
|
1123
|
-
1
|
|
1124
|
-
] } = {}) {
|
|
1125
|
-
this.wire = wire;
|
|
1126
|
-
this._defaultOrigin = toVec3(defaultOrigin);
|
|
1127
|
-
this._defaultDirection = toVec3(defaultDirection);
|
|
1128
|
-
this.baseFace = null;
|
|
1129
|
-
}
|
|
1130
|
-
get baseFace() {
|
|
1131
|
-
return this._baseFace;
|
|
1132
|
-
}
|
|
1133
|
-
set baseFace(newFace) {
|
|
1134
|
-
if (this._baseFace) this._baseFace.delete();
|
|
1135
|
-
this._baseFace = newFace ? createFace(unwrap(downcast(newFace.wrapped))) : newFace;
|
|
1136
|
-
}
|
|
1137
|
-
/** Release all kernel resources held by this sketch. */
|
|
1138
|
-
delete() {
|
|
1139
|
-
this.wire.delete();
|
|
1140
|
-
if (this.baseFace) this.baseFace.delete();
|
|
1141
|
-
}
|
|
1142
|
-
/** Create an independent deep copy of this sketch. */
|
|
1143
|
-
clone() {
|
|
1144
|
-
const sketch = new Sketch(createWire(unwrap(downcast(this.wire.wrapped))), {
|
|
1145
|
-
defaultOrigin: this.defaultOrigin,
|
|
1146
|
-
defaultDirection: this.defaultDirection
|
|
1147
|
-
});
|
|
1148
|
-
if (this.baseFace) sketch.baseFace = createFace(unwrap(downcast(this.baseFace.wrapped)));
|
|
1149
|
-
return sketch;
|
|
1150
|
-
}
|
|
1151
|
-
/** Get the 3D origin used as default for extrusion and revolution. */
|
|
1152
|
-
get defaultOrigin() {
|
|
1153
|
-
return this._defaultOrigin;
|
|
1154
|
-
}
|
|
1155
|
-
/** Set the 3D origin used as default for extrusion and revolution. */
|
|
1156
|
-
set defaultOrigin(newOrigin) {
|
|
1157
|
-
this._defaultOrigin = toVec3(newOrigin);
|
|
1158
|
-
}
|
|
1159
|
-
/** Get the default extrusion/normal direction. */
|
|
1160
|
-
get defaultDirection() {
|
|
1161
|
-
return this._defaultDirection;
|
|
1162
|
-
}
|
|
1163
|
-
/** Set the default extrusion/normal direction. */
|
|
1164
|
-
set defaultDirection(newDirection) {
|
|
1165
|
-
this._defaultDirection = toVec3(newDirection);
|
|
1166
|
-
}
|
|
1167
|
-
/**
|
|
1168
|
-
* Transforms the lines into a face. The lines should be closed.
|
|
1169
|
-
*/
|
|
1170
|
-
face() {
|
|
1171
|
-
let face;
|
|
1172
|
-
const closedWire = this.wire;
|
|
1173
|
-
if (!this.baseFace) face = unwrap(makeFace(closedWire));
|
|
1174
|
-
else face = makeNewFaceWithinFace(this.baseFace, closedWire);
|
|
1175
|
-
return face;
|
|
1176
|
-
}
|
|
1177
|
-
/** Return a clone of the underlying wire. */
|
|
1178
|
-
wires() {
|
|
1179
|
-
return createWire(unwrap(downcast(this.wire.wrapped)));
|
|
1180
|
-
}
|
|
1181
|
-
/** Alias for {@link Sketch.face}. */
|
|
1182
|
-
faces() {
|
|
1183
|
-
return this.face();
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* Revolves the drawing on an axis (defined by its direction and an origin
|
|
1187
|
-
* (defaults to the sketch origin)
|
|
1188
|
-
*/
|
|
1189
|
-
revolve(revolutionAxis, { origin } = {}) {
|
|
1190
|
-
const face = unwrap(makeFace(this.wire));
|
|
1191
|
-
const solid = unwrap(revolve(face, origin ? toVec3(origin) : this.defaultOrigin, revolutionAxis ? toVec3(revolutionAxis) : [
|
|
1192
|
-
0,
|
|
1193
|
-
0,
|
|
1194
|
-
1
|
|
1195
|
-
]));
|
|
1196
|
-
face.delete();
|
|
1197
|
-
this.delete();
|
|
1198
|
-
return solid;
|
|
1199
|
-
}
|
|
1200
|
-
/** Extrudes the sketch to a certain distance (along the default direction
|
|
1201
|
-
* and origin of the sketch).
|
|
1202
|
-
*
|
|
1203
|
-
* You can define another extrusion direction or origin,
|
|
1204
|
-
*
|
|
1205
|
-
* It is also possible to twist extrude with an angle (in degrees), or to
|
|
1206
|
-
* give a profile to the extrusion (the endFactor will scale the face, and
|
|
1207
|
-
* the profile will define how the scale is applied (either linearly or with
|
|
1208
|
-
* a s-shape).
|
|
1209
|
-
*/
|
|
1210
|
-
extrude(extrusionDistance, { extrusionDirection, extrusionProfile, twistAngle, origin } = {}) {
|
|
1211
|
-
const extrusionVec = vecScale(vecNormalize(extrusionDirection ? toVec3(extrusionDirection) : this.defaultDirection), extrusionDistance);
|
|
1212
|
-
const originVec = origin ? toVec3(origin) : this.defaultOrigin;
|
|
1213
|
-
if (extrusionProfile && !twistAngle) {
|
|
1214
|
-
const solid = unwrap(complexExtrude(this.wire, [...originVec], [...extrusionVec], extrusionProfile));
|
|
1215
|
-
this.delete();
|
|
1216
|
-
return solid;
|
|
1217
|
-
}
|
|
1218
|
-
if (twistAngle) {
|
|
1219
|
-
const solid = unwrap(twistExtrude(this.wire, twistAngle, [...originVec], [...extrusionVec], extrusionProfile));
|
|
1220
|
-
this.delete();
|
|
1221
|
-
return solid;
|
|
1222
|
-
}
|
|
1223
|
-
const solid = unwrap(extrude(unwrap(makeFace(this.wire)), [...extrusionVec]));
|
|
1224
|
-
this.delete();
|
|
1225
|
-
return solid;
|
|
1226
|
-
}
|
|
1227
|
-
/**
|
|
1228
|
-
* Sweep along this sketch another sketch defined in the function
|
|
1229
|
-
* `sketchOnPlane`.
|
|
1230
|
-
*/
|
|
1231
|
-
sweepSketch(sketchOnPlane, sweepConfig = {}) {
|
|
1232
|
-
const startPoint = curveStartPoint(this.wire);
|
|
1233
|
-
const normal = vecNormalize(vecScale(curveTangentAt(this.wire, 1e-9), -1));
|
|
1234
|
-
const defaultDir = this.defaultDirection;
|
|
1235
|
-
const xDir = vecScale(vecCross(normal, defaultDir), -1);
|
|
1236
|
-
const result = sketchOnPlane(createPlane([...startPoint], [...xDir], [...normal]), [...startPoint]);
|
|
1237
|
-
let sketch;
|
|
1238
|
-
if ("sketches" in result && Array.isArray(result.sketches)) {
|
|
1239
|
-
const pieces = result.sketches;
|
|
1240
|
-
sketch = pieces[0];
|
|
1241
|
-
for (let i = 1; i < pieces.length; i++) pieces[i]?.delete();
|
|
1242
|
-
} else sketch = result;
|
|
1243
|
-
const config = {
|
|
1244
|
-
forceProfileSpineOthogonality: true,
|
|
1245
|
-
...sweepConfig
|
|
1246
|
-
};
|
|
1247
|
-
if (this.baseFace) config.support = this.baseFace.wrapped;
|
|
1248
|
-
const shape = unwrap(sweep(sketch.wire, this.wire, config));
|
|
1249
|
-
this.delete();
|
|
1250
|
-
return shape;
|
|
1251
|
-
}
|
|
1252
|
-
/** Loft between this sketch and another sketch (or an array of them)
|
|
1253
|
-
*
|
|
1254
|
-
* You can also define a `startPoint` for the loft (that will be placed
|
|
1255
|
-
* before this sketch) and an `endPoint` after the last one.
|
|
1256
|
-
*
|
|
1257
|
-
* You can also define if you want the loft to result in a ruled surface.
|
|
1258
|
-
*
|
|
1259
|
-
* Note that all sketches will be deleted by this operation
|
|
1260
|
-
*/
|
|
1261
|
-
loftWith(otherSketches, loftConfig = {}, returnShell = false) {
|
|
1262
|
-
const sketchArray = Array.isArray(otherSketches) ? [this, ...otherSketches] : [this, otherSketches];
|
|
1263
|
-
const shape = unwrap(loft(sketchArray.map((s) => s.wire), loftConfig, returnShell));
|
|
1264
|
-
sketchArray.forEach((s) => {
|
|
1265
|
-
s.delete();
|
|
1266
|
-
});
|
|
1267
|
-
return shape;
|
|
1268
|
-
}
|
|
1269
|
-
};
|
|
1270
|
-
//#endregion
|
|
1271
|
-
//#region src/sketching/sketcherlib.ts
|
|
993
|
+
//#region src/2d/blueprints/genericSketcher.ts
|
|
1272
994
|
var isTangent = (c) => c === "symmetric" || typeof c === "number" || Array.isArray(c) && c.length === 2;
|
|
1273
995
|
/** Resolve a {@link SplineOptions} into fully-expanded tangent directions and factors. */
|
|
1274
996
|
var defaultsSplineOptions = (config) => {
|
|
@@ -1293,6 +1015,49 @@ var defaultsSplineOptions = (config) => {
|
|
|
1293
1015
|
startTangent
|
|
1294
1016
|
};
|
|
1295
1017
|
};
|
|
1018
|
+
//#endregion
|
|
1019
|
+
//#region src/2d/blueprints/ellipseUtils.ts
|
|
1020
|
+
/**
|
|
1021
|
+
* Normalize ellipse radii so that major >= minor, adjusting the rotation
|
|
1022
|
+
* angle by 90 degrees when the radii need to be swapped.
|
|
1023
|
+
*/
|
|
1024
|
+
function normalizeEllipseRadii(horizontalRadius, verticalRadius, rotation) {
|
|
1025
|
+
if (horizontalRadius < verticalRadius) return {
|
|
1026
|
+
majorRadius: verticalRadius,
|
|
1027
|
+
minorRadius: horizontalRadius,
|
|
1028
|
+
rotationAngle: rotation + 90
|
|
1029
|
+
};
|
|
1030
|
+
return {
|
|
1031
|
+
majorRadius: horizontalRadius,
|
|
1032
|
+
minorRadius: verticalRadius,
|
|
1033
|
+
rotationAngle: rotation
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* Build a 2D elliptical arc curve from SVG-style endpoint parameters,
|
|
1038
|
+
* applying the UV coordinate conversions used by {@link BaseSketcher2d}.
|
|
1039
|
+
*
|
|
1040
|
+
* @param startUV - Start point in UV space.
|
|
1041
|
+
* @param endUV - End point in UV space.
|
|
1042
|
+
* @param majorRadius - Major radius (already normalized so major >= minor).
|
|
1043
|
+
* @param minorRadius - Minor radius.
|
|
1044
|
+
* @param rotationAngleDeg - Rotation of the ellipse in degrees.
|
|
1045
|
+
* @param longAxis - SVG large-arc flag.
|
|
1046
|
+
* @param sweep - SVG sweep flag.
|
|
1047
|
+
* @param convertToUV - Coordinate conversion function from user space to UV space.
|
|
1048
|
+
*/
|
|
1049
|
+
function makeEllipseArcFromSvgParams(startUV, endUV, majorRadius, minorRadius, rotationAngleDeg, longAxis, sweep, convertToUV) {
|
|
1050
|
+
const radRotationAngle = rotationAngleDeg * DEG2RAD;
|
|
1051
|
+
const convertAxis = (ax) => distance2d(convertToUV(ax));
|
|
1052
|
+
const r1 = convertAxis(polarToCartesian(majorRadius, radRotationAngle));
|
|
1053
|
+
const r2 = convertAxis(polarToCartesian(minorRadius, radRotationAngle + Math.PI / 2));
|
|
1054
|
+
const xDir = normalize2d(convertToUV(rotate2d([1, 0], radRotationAngle)));
|
|
1055
|
+
const [, newRotationAngle] = cartesianToPolar(xDir);
|
|
1056
|
+
const { cx, cy, startAngle, endAngle, clockwise, rx, ry } = convertSvgEllipseParams(startUV, endUV, r1, r2, newRotationAngle, longAxis, sweep);
|
|
1057
|
+
const arc = make2dEllipseArc(rx, ry, clockwise ? startAngle : endAngle, clockwise ? endAngle : startAngle, [cx, cy], xDir);
|
|
1058
|
+
if (!clockwise) arc.reverse();
|
|
1059
|
+
return arc;
|
|
1060
|
+
}
|
|
1296
1061
|
/**
|
|
1297
1062
|
* Compute start/delta/end angles from the unit-circle parameterization
|
|
1298
1063
|
* of an SVG elliptical arc (F6.5.5–F6.5.6).
|
|
@@ -1372,50 +1137,7 @@ function convertSvgEllipseParams([x1, y1], [x2, y2], rx, ry, phi, fA, fS) {
|
|
|
1372
1137
|
};
|
|
1373
1138
|
}
|
|
1374
1139
|
//#endregion
|
|
1375
|
-
//#region src/
|
|
1376
|
-
/**
|
|
1377
|
-
* Normalize ellipse radii so that major >= minor, adjusting the rotation
|
|
1378
|
-
* angle by 90 degrees when the radii need to be swapped.
|
|
1379
|
-
*/
|
|
1380
|
-
function normalizeEllipseRadii(horizontalRadius, verticalRadius, rotation) {
|
|
1381
|
-
if (horizontalRadius < verticalRadius) return {
|
|
1382
|
-
majorRadius: verticalRadius,
|
|
1383
|
-
minorRadius: horizontalRadius,
|
|
1384
|
-
rotationAngle: rotation + 90
|
|
1385
|
-
};
|
|
1386
|
-
return {
|
|
1387
|
-
majorRadius: horizontalRadius,
|
|
1388
|
-
minorRadius: verticalRadius,
|
|
1389
|
-
rotationAngle: rotation
|
|
1390
|
-
};
|
|
1391
|
-
}
|
|
1392
|
-
/**
|
|
1393
|
-
* Build a 2D elliptical arc curve from SVG-style endpoint parameters,
|
|
1394
|
-
* applying the UV coordinate conversions used by {@link BaseSketcher2d}.
|
|
1395
|
-
*
|
|
1396
|
-
* @param startUV - Start point in UV space.
|
|
1397
|
-
* @param endUV - End point in UV space.
|
|
1398
|
-
* @param majorRadius - Major radius (already normalized so major >= minor).
|
|
1399
|
-
* @param minorRadius - Minor radius.
|
|
1400
|
-
* @param rotationAngleDeg - Rotation of the ellipse in degrees.
|
|
1401
|
-
* @param longAxis - SVG large-arc flag.
|
|
1402
|
-
* @param sweep - SVG sweep flag.
|
|
1403
|
-
* @param convertToUV - Coordinate conversion function from user space to UV space.
|
|
1404
|
-
*/
|
|
1405
|
-
function makeEllipseArcFromSvgParams(startUV, endUV, majorRadius, minorRadius, rotationAngleDeg, longAxis, sweep, convertToUV) {
|
|
1406
|
-
const radRotationAngle = rotationAngleDeg * DEG2RAD;
|
|
1407
|
-
const convertAxis = (ax) => distance2d(convertToUV(ax));
|
|
1408
|
-
const r1 = convertAxis(polarToCartesian(majorRadius, radRotationAngle));
|
|
1409
|
-
const r2 = convertAxis(polarToCartesian(minorRadius, radRotationAngle + Math.PI / 2));
|
|
1410
|
-
const xDir = normalize2d(convertToUV(rotate2d([1, 0], radRotationAngle)));
|
|
1411
|
-
const [, newRotationAngle] = cartesianToPolar(xDir);
|
|
1412
|
-
const { cx, cy, startAngle, endAngle, clockwise, rx, ry } = convertSvgEllipseParams(startUV, endUV, r1, r2, newRotationAngle, longAxis, sweep);
|
|
1413
|
-
const arc = make2dEllipseArc(rx, ry, clockwise ? startAngle : endAngle, clockwise ? endAngle : startAngle, [cx, cy], xDir);
|
|
1414
|
-
if (!clockwise) arc.reverse();
|
|
1415
|
-
return arc;
|
|
1416
|
-
}
|
|
1417
|
-
//#endregion
|
|
1418
|
-
//#region src/sketching/sketcher2d.ts
|
|
1140
|
+
//#region src/2d/blueprints/baseSketcher2d.ts
|
|
1419
1141
|
var cornerModeFns = {
|
|
1420
1142
|
chamfer: chamferCurves,
|
|
1421
1143
|
dogbone: dogboneFilletCurves,
|
|
@@ -1430,7 +1152,7 @@ function buildCornerFunction(radius, mode) {
|
|
|
1430
1152
|
* Base class for 2D sketchers that accumulate {@link Curve2D} segments.
|
|
1431
1153
|
*
|
|
1432
1154
|
* Provides the shared pen-drawing API (lines, arcs, ellipses, beziers, splines)
|
|
1433
|
-
* used by
|
|
1155
|
+
* used by `FaceSketcher`, `BlueprintSketcher`, and `DrawingPen`.
|
|
1434
1156
|
* Subclasses implement `done()` / `close()` to produce the appropriate output type.
|
|
1435
1157
|
*
|
|
1436
1158
|
* @category Sketching
|
|
@@ -1452,23 +1174,19 @@ var BaseSketcher2d = class {
|
|
|
1452
1174
|
_convertFromUV([u, v]) {
|
|
1453
1175
|
return [u, v];
|
|
1454
1176
|
}
|
|
1455
|
-
/** Return the last curve in the pending list, or null if empty. */
|
|
1456
1177
|
_lastCurve() {
|
|
1457
1178
|
const len = this.pendingCurves.length;
|
|
1458
1179
|
if (len === 0) return null;
|
|
1459
1180
|
return this.pendingCurves[len - 1];
|
|
1460
1181
|
}
|
|
1461
|
-
/** Require that a previous curve exists, returning it or throwing. */
|
|
1462
1182
|
_requireLastCurve(caller, action) {
|
|
1463
1183
|
const curve = this._lastCurve();
|
|
1464
1184
|
if (!curve) bug(caller, `You need a previous curve to ${action}`);
|
|
1465
1185
|
return curve;
|
|
1466
1186
|
}
|
|
1467
|
-
/** Resolve a relative offset from the current pointer position. */
|
|
1468
1187
|
_resolveRelative(xDist, yDist) {
|
|
1469
1188
|
return [this.pointer[0] + xDist, this.pointer[1] + yDist];
|
|
1470
1189
|
}
|
|
1471
|
-
/** Save a curve, advance the pointer to the given end point, and return `this`. */
|
|
1472
1190
|
_saveCurveAndAdvance(curve, end) {
|
|
1473
1191
|
this.saveCurve(curve);
|
|
1474
1192
|
this.pointer = end;
|
|
@@ -1485,10 +1203,6 @@ var BaseSketcher2d = class {
|
|
|
1485
1203
|
/**
|
|
1486
1204
|
* Returns the current pen angle in degrees
|
|
1487
1205
|
*
|
|
1488
|
-
* The angle represents the tangent direction at the current pen position,
|
|
1489
|
-
* based on the last drawing operation (line, arc, bezier, etc.).
|
|
1490
|
-
* Returns 0 if nothing has been drawn yet.
|
|
1491
|
-
*
|
|
1492
1206
|
* @category Drawing State
|
|
1493
1207
|
*/
|
|
1494
1208
|
get penAngle() {
|
|
@@ -1674,9 +1388,7 @@ var BaseSketcher2d = class {
|
|
|
1674
1388
|
smoothSpline(xDist, yDist, splineConfig) {
|
|
1675
1389
|
return this.smoothSplineTo(this._resolveRelative(xDist, yDist), splineConfig);
|
|
1676
1390
|
}
|
|
1677
|
-
/**
|
|
1678
|
-
* Changes the corner between the previous and next segments.
|
|
1679
|
-
*/
|
|
1391
|
+
/** Changes the corner between the previous and next segments. */
|
|
1680
1392
|
customCorner(radius, mode = "fillet") {
|
|
1681
1393
|
if (!this.pendingCurves.length) bug("Sketcher2d.customCorner", "You need a curve defined to fillet the angle");
|
|
1682
1394
|
this._nextCorner = buildCornerFunction(radius, mode);
|
|
@@ -1690,10 +1402,10 @@ var BaseSketcher2d = class {
|
|
|
1690
1402
|
this.pendingCurves.push(...buildCornerFunction(radius, mode)(previousCurve, curve));
|
|
1691
1403
|
}
|
|
1692
1404
|
_closeSketch() {
|
|
1693
|
-
if (!samePoint
|
|
1405
|
+
if (!samePoint(this.pointer, this.firstPoint)) this.lineTo(this.firstPoint);
|
|
1694
1406
|
}
|
|
1695
1407
|
_closeWithMirror() {
|
|
1696
|
-
if (samePoint
|
|
1408
|
+
if (samePoint(this.pointer, this.firstPoint)) bug("Sketcher2d._closeWithMirror", "Cannot close with a mirror when the sketch is already closed");
|
|
1697
1409
|
const startToEndVector = [this.pointer[0] - this.firstPoint[0], this.pointer[1] - this.firstPoint[1]];
|
|
1698
1410
|
const uvOrigin = this._convertToUV(this.pointer);
|
|
1699
1411
|
const uvDir = this._convertToUV(startToEndVector);
|
|
@@ -1704,127 +1416,14 @@ var BaseSketcher2d = class {
|
|
|
1704
1416
|
this.pointer = this.firstPoint;
|
|
1705
1417
|
}
|
|
1706
1418
|
};
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
* instance the sides of a cylinder.
|
|
1710
|
-
*
|
|
1711
|
-
* The coordinates passed to the methods corresponds to normalised distances on
|
|
1712
|
-
* this surface, between 0 and 1 in both direction.
|
|
1713
|
-
*
|
|
1714
|
-
* Note that if you are drawing on a closed surface (typically a revolution
|
|
1715
|
-
* surface or a cylinder), the first parameters represents the angle and can be
|
|
1716
|
-
* smaller than 0 or bigger than 1.
|
|
1717
|
-
*
|
|
1718
|
-
* @category Sketching
|
|
1719
|
-
*/
|
|
1720
|
-
var FaceSketcher = class extends BaseSketcher2d {
|
|
1721
|
-
face;
|
|
1722
|
-
_bounds;
|
|
1723
|
-
constructor(face, origin = [0, 0]) {
|
|
1724
|
-
super(origin);
|
|
1725
|
-
this.face = createFace(unwrap(downcast(face.wrapped)));
|
|
1726
|
-
this._bounds = uvBounds(face);
|
|
1727
|
-
}
|
|
1728
|
-
_convertToUV([x, y]) {
|
|
1729
|
-
const { uMin, uMax, vMin, vMax } = this._bounds;
|
|
1730
|
-
return [uMin + x * (uMax - uMin), vMin + y * (vMax - vMin)];
|
|
1731
|
-
}
|
|
1732
|
-
_convertFromUV([u, v]) {
|
|
1733
|
-
const { uMin, uMax, vMin, vMax } = this._bounds;
|
|
1734
|
-
return [(u - uMin) / (uMax - uMin), (v - vMin) / (vMax - vMin)];
|
|
1735
|
-
}
|
|
1736
|
-
_adaptSurface() {
|
|
1737
|
-
return getKernel().extractSurfaceFromFace(this.face.wrapped);
|
|
1738
|
-
}
|
|
1739
|
-
/**
|
|
1740
|
-
* @ignore
|
|
1741
|
-
*/
|
|
1742
|
-
buildWire() {
|
|
1743
|
-
const kernel = getKernel();
|
|
1744
|
-
const geomSurf = this._adaptSurface();
|
|
1745
|
-
const wire = unwrap(assembleWire(this.pendingCurves.map((curve) => {
|
|
1746
|
-
return createEdge(kernel.buildEdgeOnSurface(curve.wrapped, geomSurf));
|
|
1747
|
-
})));
|
|
1748
|
-
kernel.buildCurves3d(wire.wrapped);
|
|
1749
|
-
return wire;
|
|
1750
|
-
}
|
|
1751
|
-
/** Finish drawing and return the resulting {@link Sketch} (does not close the path). */
|
|
1752
|
-
done() {
|
|
1753
|
-
try {
|
|
1754
|
-
var _usingCtx$1 = _usingCtx();
|
|
1755
|
-
const scope = _usingCtx$1.u(new DisposalScope());
|
|
1756
|
-
const wire = this.buildWire();
|
|
1757
|
-
const sketch = new Sketch(wire);
|
|
1758
|
-
if (curveIsClosed(wire)) {
|
|
1759
|
-
const face = scope.register(sketch.clone().face());
|
|
1760
|
-
const origin = pointOnSurface(face, .5, .5);
|
|
1761
|
-
const direction = vecScale(normalAt(face), -1);
|
|
1762
|
-
sketch.defaultOrigin = [
|
|
1763
|
-
origin[0],
|
|
1764
|
-
origin[1],
|
|
1765
|
-
origin[2]
|
|
1766
|
-
];
|
|
1767
|
-
sketch.defaultDirection = [
|
|
1768
|
-
direction[0],
|
|
1769
|
-
direction[1],
|
|
1770
|
-
direction[2]
|
|
1771
|
-
];
|
|
1772
|
-
} else {
|
|
1773
|
-
const startPoint = curveStartPoint(wire);
|
|
1774
|
-
const normal = normalAt(this.face, [
|
|
1775
|
-
startPoint[0],
|
|
1776
|
-
startPoint[1],
|
|
1777
|
-
startPoint[2]
|
|
1778
|
-
]);
|
|
1779
|
-
sketch.defaultOrigin = [
|
|
1780
|
-
startPoint[0],
|
|
1781
|
-
startPoint[1],
|
|
1782
|
-
startPoint[2]
|
|
1783
|
-
];
|
|
1784
|
-
sketch.defaultDirection = [
|
|
1785
|
-
normal[0],
|
|
1786
|
-
normal[1],
|
|
1787
|
-
normal[2]
|
|
1788
|
-
];
|
|
1789
|
-
}
|
|
1790
|
-
sketch.baseFace = this.face;
|
|
1791
|
-
return sketch;
|
|
1792
|
-
} catch (_) {
|
|
1793
|
-
_usingCtx$1.e = _;
|
|
1794
|
-
} finally {
|
|
1795
|
-
_usingCtx$1.d();
|
|
1796
|
-
}
|
|
1797
|
-
}
|
|
1798
|
-
/** Close the path with a straight line to the start point and return the Sketch. */
|
|
1799
|
-
close() {
|
|
1800
|
-
this._closeSketch();
|
|
1801
|
-
return this.done();
|
|
1802
|
-
}
|
|
1803
|
-
/** Close the path by mirroring all curves about the line from first to last point. */
|
|
1804
|
-
closeWithMirror() {
|
|
1805
|
-
this._closeWithMirror();
|
|
1806
|
-
return this.close();
|
|
1807
|
-
}
|
|
1808
|
-
/**
|
|
1809
|
-
* Close the path and apply a custom corner treatment between the last and first segments.
|
|
1810
|
-
*
|
|
1811
|
-
* @param radius - Fillet/chamfer radius, or a custom corner function.
|
|
1812
|
-
* @param mode - Corner treatment type.
|
|
1813
|
-
* @returns The closed {@link Sketch}.
|
|
1814
|
-
*/
|
|
1815
|
-
closeWithCustomCorner(radius, mode = "fillet") {
|
|
1816
|
-
this._closeSketch();
|
|
1817
|
-
this._customCornerLastWithFirst(radius, mode);
|
|
1818
|
-
return this.done();
|
|
1819
|
-
}
|
|
1820
|
-
};
|
|
1419
|
+
//#endregion
|
|
1420
|
+
//#region src/2d/blueprints/blueprintSketcher.ts
|
|
1821
1421
|
/**
|
|
1822
1422
|
* Draw 2D curves and produce a {@link Blueprint} (pure-2D shape, no kernel wire).
|
|
1823
1423
|
*
|
|
1824
1424
|
* Use this when you need a reusable 2D profile that can later be sketched onto
|
|
1825
1425
|
* different planes or faces.
|
|
1826
1426
|
*
|
|
1827
|
-
* @see {@link DrawingPen} for the higher-level Drawing wrapper.
|
|
1828
1427
|
* @category Sketching
|
|
1829
1428
|
*/
|
|
1830
1429
|
var BlueprintSketcher = class extends BaseSketcher2d {
|
|
@@ -1862,851 +1461,4 @@ var BlueprintSketcher = class extends BaseSketcher2d {
|
|
|
1862
1461
|
}
|
|
1863
1462
|
};
|
|
1864
1463
|
//#endregion
|
|
1865
|
-
|
|
1866
|
-
/**
|
|
1867
|
-
* Create a regular polygon blueprint inscribed in a circle of the given radius.
|
|
1868
|
-
*
|
|
1869
|
-
* @param radius - Circumscribed circle radius.
|
|
1870
|
-
* @param sidesCount - Number of sides (3 = triangle, 6 = hexagon, etc.).
|
|
1871
|
-
* @param sagitta - When non-zero, sides are replaced by sagitta arcs (bulge height).
|
|
1872
|
-
* @returns A closed Blueprint representing the polygon.
|
|
1873
|
-
*
|
|
1874
|
-
* @example
|
|
1875
|
-
* ```ts
|
|
1876
|
-
* const hexagon = polysidesBlueprint(10, 6);
|
|
1877
|
-
* const roundedTriangle = polysidesBlueprint(10, 3, 2);
|
|
1878
|
-
* ```
|
|
1879
|
-
*/
|
|
1880
|
-
var polysidesBlueprint = (radius, sidesCount, sagitta = 0) => {
|
|
1881
|
-
const points = [...Array(sidesCount).keys()].map((i) => {
|
|
1882
|
-
const theta = -(Math.PI * 2 / sidesCount) * i;
|
|
1883
|
-
return [radius * Math.sin(theta), radius * Math.cos(theta)];
|
|
1884
|
-
});
|
|
1885
|
-
const lastPoint = lastOrThrow(points);
|
|
1886
|
-
const blueprint = new BlueprintSketcher().movePointerTo([lastPoint[0], lastPoint[1]]);
|
|
1887
|
-
if (sagitta) points.forEach(([x, y]) => blueprint.sagittaArcTo([x, y], sagitta));
|
|
1888
|
-
else points.forEach(([x, y]) => blueprint.lineTo([x, y]));
|
|
1889
|
-
return blueprint.done();
|
|
1890
|
-
};
|
|
1891
|
-
/**
|
|
1892
|
-
* Create an axis-aligned rectangle blueprint with optional rounded corners.
|
|
1893
|
-
*
|
|
1894
|
-
* The rectangle is centered at the origin. When `r` is zero the corners
|
|
1895
|
-
* are sharp; otherwise they are filleted with circular or elliptical arcs.
|
|
1896
|
-
*
|
|
1897
|
-
* @param width - Total width of the rectangle.
|
|
1898
|
-
* @param height - Total height of the rectangle.
|
|
1899
|
-
* @param r - Corner radius. Pass a number for uniform rounding, or
|
|
1900
|
-
* `{ rx, ry }` for elliptical corners. Clamped to half the respective
|
|
1901
|
-
* dimension.
|
|
1902
|
-
* @returns A closed Blueprint representing the rectangle.
|
|
1903
|
-
*
|
|
1904
|
-
* @example
|
|
1905
|
-
* ```ts
|
|
1906
|
-
* const sharp = roundedRectangleBlueprint(20, 10);
|
|
1907
|
-
* const rounded = roundedRectangleBlueprint(20, 10, 3);
|
|
1908
|
-
* const elliptical = roundedRectangleBlueprint(20, 10, { rx: 4, ry: 2 });
|
|
1909
|
-
* ```
|
|
1910
|
-
*/
|
|
1911
|
-
var roundedRectangleBlueprint = (width, height, r = 0) => {
|
|
1912
|
-
const { rx: inputRx = 0, ry: inputRy = 0 } = typeof r === "number" ? {
|
|
1913
|
-
ry: r,
|
|
1914
|
-
rx: r
|
|
1915
|
-
} : r;
|
|
1916
|
-
let rx = Math.min(inputRx, width / 2);
|
|
1917
|
-
let ry = Math.min(inputRy, height / 2);
|
|
1918
|
-
const withRadius = rx && ry;
|
|
1919
|
-
if (!withRadius) {
|
|
1920
|
-
rx = 0;
|
|
1921
|
-
ry = 0;
|
|
1922
|
-
}
|
|
1923
|
-
const symmetricRadius = rx === ry;
|
|
1924
|
-
const sk = new BlueprintSketcher([Math.min(0, -(width / 2 - rx)), -height / 2]);
|
|
1925
|
-
const addFillet = (xDist, yDist) => {
|
|
1926
|
-
if (withRadius) if (symmetricRadius) sk.tangentArc(xDist, yDist);
|
|
1927
|
-
else sk.ellipse(xDist, yDist, rx, ry, 0, false, true);
|
|
1928
|
-
};
|
|
1929
|
-
if (rx < width / 2) sk.hLine(width - 2 * rx);
|
|
1930
|
-
addFillet(rx, ry);
|
|
1931
|
-
if (ry < height / 2) sk.vLine(height - 2 * ry);
|
|
1932
|
-
addFillet(-rx, ry);
|
|
1933
|
-
if (rx < width / 2) sk.hLine(-(width - 2 * rx));
|
|
1934
|
-
addFillet(-rx, -ry);
|
|
1935
|
-
if (ry < height / 2) sk.vLine(-(height - 2 * ry));
|
|
1936
|
-
addFillet(rx, -ry);
|
|
1937
|
-
return sk.close();
|
|
1938
|
-
};
|
|
1939
|
-
//#endregion
|
|
1940
|
-
//#region src/2d/blueprints/booleanHelpers.ts
|
|
1941
|
-
var samePoint = (x, y) => samePoint$1(x, y, PRECISION_INTERSECTION);
|
|
1942
|
-
/**
|
|
1943
|
-
* Hash a point for Set/Map lookup using precision rounding.
|
|
1944
|
-
* Must match PRECISION_INTERSECTION (1e-9) to avoid hash collisions for
|
|
1945
|
-
* nearly-equal points.
|
|
1946
|
-
*/
|
|
1947
|
-
function hashPoint(p) {
|
|
1948
|
-
return `${p[0].toFixed(9)},${p[1].toFixed(9)}`;
|
|
1949
|
-
}
|
|
1950
|
-
/**
|
|
1951
|
-
* Hash a segment by both orientations for bidirectional lookup.
|
|
1952
|
-
* The smaller hash comes first so that (A,B) and (B,A) produce the same key.
|
|
1953
|
-
*/
|
|
1954
|
-
function hashSegment(first, last) {
|
|
1955
|
-
const h1 = hashPoint(first);
|
|
1956
|
-
const h2 = hashPoint(last);
|
|
1957
|
-
return h1 < h2 ? `${h1}|${h2}` : `${h2}|${h1}`;
|
|
1958
|
-
}
|
|
1959
|
-
function startOfSegment(s) {
|
|
1960
|
-
const first = s[0];
|
|
1961
|
-
if (first === void 0) bug("startOfSegment", "empty segment");
|
|
1962
|
-
return first.firstPoint;
|
|
1963
|
-
}
|
|
1964
|
-
function endOfSegment(s) {
|
|
1965
|
-
const last = s[s.length - 1];
|
|
1966
|
-
if (last === void 0) bug("endOfSegment", "empty segment");
|
|
1967
|
-
return last.lastPoint;
|
|
1968
|
-
}
|
|
1969
|
-
function reverseSegment(segment) {
|
|
1970
|
-
return [...segment].reverse().map((curve) => {
|
|
1971
|
-
const newCurve = curve.clone();
|
|
1972
|
-
newCurve.reverse();
|
|
1973
|
-
return newCurve;
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
function reverseSegments(segments) {
|
|
1977
|
-
return [...segments].reverse().map(reverseSegment);
|
|
1978
|
-
}
|
|
1979
|
-
function curveMidPoint(curve) {
|
|
1980
|
-
const midParameter = (curve.lastParameter + curve.firstParameter) / 2;
|
|
1981
|
-
return curve.value(midParameter);
|
|
1982
|
-
}
|
|
1983
|
-
/**
|
|
1984
|
-
* Find the index of the first curve in `curves` whose firstPoint matches
|
|
1985
|
-
* `point`. Uses hash for a fast first pass, then falls back to tolerance-only
|
|
1986
|
-
* comparison to handle floating-point rounding at `toFixed(9)` boundaries.
|
|
1987
|
-
* Returns -1 if no match is found.
|
|
1988
|
-
*/
|
|
1989
|
-
function findCurveIndexByStartPoint(curves, point) {
|
|
1990
|
-
const targetHash = hashPoint(point);
|
|
1991
|
-
for (let i = 0; i < curves.length; i++) {
|
|
1992
|
-
const curve = curves[i];
|
|
1993
|
-
if (curve === void 0) continue;
|
|
1994
|
-
if (hashPoint(curve.firstPoint) === targetHash && samePoint(point, curve.firstPoint)) return i;
|
|
1995
|
-
}
|
|
1996
|
-
for (let i = 0; i < curves.length; i++) {
|
|
1997
|
-
const curve = curves[i];
|
|
1998
|
-
if (curve === void 0) continue;
|
|
1999
|
-
if (samePoint(point, curve.firstPoint)) return i;
|
|
2000
|
-
}
|
|
2001
|
-
return -1;
|
|
2002
|
-
}
|
|
2003
|
-
/**
|
|
2004
|
-
* Find the index of the first curve in `curves` that matches the given
|
|
2005
|
-
* segment's start and end points. Uses hash for a fast first pass, then
|
|
2006
|
-
* falls back to tolerance-only comparison.
|
|
2007
|
-
* Returns -1 if no match is found.
|
|
2008
|
-
*/
|
|
2009
|
-
function findCurveIndexBySegment(curves, segFirstHash, segLastHash, matchesFn) {
|
|
2010
|
-
for (let i = 0; i < curves.length; i++) {
|
|
2011
|
-
const curve = curves[i];
|
|
2012
|
-
if (curve === void 0) continue;
|
|
2013
|
-
if (hashPoint(curve.firstPoint) === segFirstHash && hashPoint(curve.lastPoint) === segLastHash && matchesFn(curve)) return i;
|
|
2014
|
-
}
|
|
2015
|
-
for (let i = 0; i < curves.length; i++) {
|
|
2016
|
-
const curve = curves[i];
|
|
2017
|
-
if (curve === void 0) continue;
|
|
2018
|
-
if (matchesFn(curve)) return i;
|
|
2019
|
-
}
|
|
2020
|
-
return -1;
|
|
2021
|
-
}
|
|
2022
|
-
/** Rotate an array so that element at `startIndex` becomes the first element. */
|
|
2023
|
-
function rotateArray(arr, startIndex) {
|
|
2024
|
-
if (startIndex <= 0) return arr;
|
|
2025
|
-
return arr.slice(startIndex).concat(arr.slice(0, startIndex));
|
|
2026
|
-
}
|
|
2027
|
-
/**
|
|
2028
|
-
* Rotate the curves array so that it starts at the curve whose firstPoint
|
|
2029
|
-
* matches the given point.
|
|
2030
|
-
*/
|
|
2031
|
-
function rotateToStartAt(curves, point) {
|
|
2032
|
-
return rotateArray(curves, findCurveIndexByStartPoint(curves, point));
|
|
2033
|
-
}
|
|
2034
|
-
/**
|
|
2035
|
-
* Rotate the curves array so that it starts at the curve matching the given
|
|
2036
|
-
* segment. Tries both segment orientations (forward and flipped) against both
|
|
2037
|
-
* curve orientations (original and reversed chain) to handle cases where
|
|
2038
|
-
* `intersectCurves` returns a common segment oriented opposite to the
|
|
2039
|
-
* matching curve in the split result.
|
|
2040
|
-
*/
|
|
2041
|
-
function rotateToStartAtSegment(curves, segment) {
|
|
2042
|
-
const segFirstHash = hashPoint(segment.firstPoint);
|
|
2043
|
-
const segLastHash = hashPoint(segment.lastPoint);
|
|
2044
|
-
const matchesForward = (curve) => samePoint(segment.firstPoint, curve.firstPoint) && samePoint(segment.lastPoint, curve.lastPoint);
|
|
2045
|
-
const matchesFlipped = (curve) => samePoint(segment.lastPoint, curve.firstPoint) && samePoint(segment.firstPoint, curve.lastPoint);
|
|
2046
|
-
function tryRotate(chain, firstHash, lastHash, matchFn) {
|
|
2047
|
-
const idx = findCurveIndexBySegment(chain, firstHash, lastHash, matchFn);
|
|
2048
|
-
return idx !== -1 ? rotateArray(chain, idx) : null;
|
|
2049
|
-
}
|
|
2050
|
-
const fwdFwd = tryRotate(curves, segFirstHash, segLastHash, matchesForward);
|
|
2051
|
-
if (fwdFwd !== null) return fwdFwd;
|
|
2052
|
-
const flipFwd = tryRotate(curves, segLastHash, segFirstHash, matchesFlipped);
|
|
2053
|
-
if (flipFwd !== null) return flipFwd;
|
|
2054
|
-
const reversed = reverseSegment(curves);
|
|
2055
|
-
const fwdRev = tryRotate(reversed, segFirstHash, segLastHash, matchesForward);
|
|
2056
|
-
if (fwdRev !== null) return fwdRev;
|
|
2057
|
-
const flipRev = tryRotate(reversed, segLastHash, segFirstHash, matchesFlipped);
|
|
2058
|
-
if (flipRev !== null) return flipRev;
|
|
2059
|
-
bug("rotateToStartAtSegment", "failed to rotate to segment start");
|
|
2060
|
-
}
|
|
2061
|
-
//#endregion
|
|
2062
|
-
//#region src/2d/blueprints/intersectionSegments.ts
|
|
2063
|
-
function* createSegmentOnPoints(curves, allIntersections, allCommonSegments) {
|
|
2064
|
-
const intersectionSet = new Set(allIntersections.map(hashPoint));
|
|
2065
|
-
const commonSegmentSet = new Set(allCommonSegments.map((seg) => hashSegment(seg.firstPoint, seg.lastPoint)));
|
|
2066
|
-
const matchesIntersection = (point) => {
|
|
2067
|
-
if (intersectionSet.has(hashPoint(point))) return true;
|
|
2068
|
-
return allIntersections.some((p) => samePoint(p, point));
|
|
2069
|
-
};
|
|
2070
|
-
const matchesCommonSegment = (first, last) => {
|
|
2071
|
-
if (commonSegmentSet.has(hashSegment(first, last))) return true;
|
|
2072
|
-
return allCommonSegments.some((seg) => samePoint(seg.firstPoint, first) && samePoint(seg.lastPoint, last) || samePoint(seg.firstPoint, last) && samePoint(seg.lastPoint, first));
|
|
2073
|
-
};
|
|
2074
|
-
let currentCurves = [];
|
|
2075
|
-
for (const curve of curves) {
|
|
2076
|
-
if (samePoint(curve.firstPoint, curve.lastPoint)) {
|
|
2077
|
-
currentCurves.push(curve);
|
|
2078
|
-
continue;
|
|
2079
|
-
}
|
|
2080
|
-
const endsAtIntersection = matchesIntersection(curve.lastPoint);
|
|
2081
|
-
const isCommon = matchesCommonSegment(curve.firstPoint, curve.lastPoint);
|
|
2082
|
-
if (endsAtIntersection) {
|
|
2083
|
-
currentCurves.push(curve);
|
|
2084
|
-
yield currentCurves;
|
|
2085
|
-
currentCurves = [];
|
|
2086
|
-
} else if (isCommon) {
|
|
2087
|
-
if (currentCurves.length) {
|
|
2088
|
-
yield currentCurves;
|
|
2089
|
-
currentCurves = [];
|
|
2090
|
-
}
|
|
2091
|
-
yield [curve];
|
|
2092
|
-
} else currentCurves.push(curve);
|
|
2093
|
-
}
|
|
2094
|
-
if (currentCurves.length) yield currentCurves;
|
|
2095
|
-
}
|
|
2096
|
-
/**
|
|
2097
|
-
* Filter out intersection points where the curves only touch but do not
|
|
2098
|
-
* actually cross from one side to the other.
|
|
2099
|
-
*/
|
|
2100
|
-
function removeNonCrossingPoints(allIntersections, segmentedCurve, blueprintToCheck) {
|
|
2101
|
-
return allIntersections.filter((intersection) => {
|
|
2102
|
-
const touching = segmentedCurve.filter((s) => samePoint(s.firstPoint, intersection) || samePoint(s.lastPoint, intersection));
|
|
2103
|
-
const effectiveTouching = touching.length % 2 ? touching.filter((s) => !(samePoint(s.firstPoint, intersection) && samePoint(s.lastPoint, intersection))) : touching;
|
|
2104
|
-
if (effectiveTouching.length === 0 || effectiveTouching.length % 2) return false;
|
|
2105
|
-
const insideFlags = effectiveTouching.map((segment) => blueprintToCheck.isInside(curveMidPoint(segment)));
|
|
2106
|
-
return !(insideFlags.every(Boolean) || insideFlags.every((f) => !f));
|
|
2107
|
-
});
|
|
2108
|
-
}
|
|
2109
|
-
/**
|
|
2110
|
-
* Find all intersection points and common segments between two blueprints'
|
|
2111
|
-
* curves. Returns per-curve intersection points for subsequent splitting.
|
|
2112
|
-
*/
|
|
2113
|
-
function findAllIntersections(first, second) {
|
|
2114
|
-
const allIntersections = [];
|
|
2115
|
-
const allCommonSegments = [];
|
|
2116
|
-
const firstCurvePoints = first.curves.map(() => []);
|
|
2117
|
-
const secondCurvePoints = second.curves.map(() => []);
|
|
2118
|
-
const secondIndex = new Flatbush(second.curves.length);
|
|
2119
|
-
for (const curve of second.curves) {
|
|
2120
|
-
const [[xMin, yMin], [xMax, yMax]] = curve.boundingBox.bounds;
|
|
2121
|
-
secondIndex.add(xMin, yMin, xMax, yMax);
|
|
2122
|
-
}
|
|
2123
|
-
secondIndex.finish();
|
|
2124
|
-
first.curves.forEach((thisCurve, firstIdx) => {
|
|
2125
|
-
const [[xMin, yMin], [xMax, yMax]] = thisCurve.boundingBox.bounds;
|
|
2126
|
-
const candidates = secondIndex.search(xMin, yMin, xMax, yMax);
|
|
2127
|
-
for (const secondIdx of candidates) {
|
|
2128
|
-
const { intersections, commonSegments, commonSegmentsPoints } = unwrap(intersectCurves(thisCurve, wasmIndex(second.curves, secondIdx), PRECISION_INTERSECTION / 100));
|
|
2129
|
-
allIntersections.push(...intersections);
|
|
2130
|
-
firstCurvePoints[firstIdx]?.push(...intersections);
|
|
2131
|
-
secondCurvePoints[secondIdx]?.push(...intersections);
|
|
2132
|
-
allCommonSegments.push(...commonSegments);
|
|
2133
|
-
allIntersections.push(...commonSegmentsPoints);
|
|
2134
|
-
firstCurvePoints[firstIdx]?.push(...commonSegmentsPoints);
|
|
2135
|
-
secondCurvePoints[secondIdx]?.push(...commonSegmentsPoints);
|
|
2136
|
-
}
|
|
2137
|
-
});
|
|
2138
|
-
return {
|
|
2139
|
-
allIntersections: removeDuplicatePoints(allIntersections, PRECISION_INTERSECTION),
|
|
2140
|
-
allCommonSegments,
|
|
2141
|
-
firstCurvePoints,
|
|
2142
|
-
secondCurvePoints
|
|
2143
|
-
};
|
|
2144
|
-
}
|
|
2145
|
-
/**
|
|
2146
|
-
* Split each curve at its intersection points and return the resulting
|
|
2147
|
-
* sub-curves.
|
|
2148
|
-
*/
|
|
2149
|
-
function splitCurvesAtIntersections(curves, curvePoints) {
|
|
2150
|
-
return zip([curves, curvePoints]).flatMap(([curve, intersections]) => {
|
|
2151
|
-
if (intersections.length === 0) return [curve];
|
|
2152
|
-
return curve.splitAt(intersections, PRECISION_INTERSECTION / 100);
|
|
2153
|
-
});
|
|
2154
|
-
}
|
|
2155
|
-
/**
|
|
2156
|
-
* Check whether a segment's start/end points match one of the common segment
|
|
2157
|
-
* point pairs.
|
|
2158
|
-
*/
|
|
2159
|
-
function isCommonSegmentMatch(commonSegmentsPoints, segmentStart, segmentEnd) {
|
|
2160
|
-
return commonSegmentsPoints.some(([startPoint, endPoint]) => {
|
|
2161
|
-
if (startPoint === void 0 || endPoint === void 0) return false;
|
|
2162
|
-
return samePoint(startPoint, segmentStart) && samePoint(endPoint, segmentEnd) || samePoint(startPoint, segmentEnd) && samePoint(endPoint, segmentStart);
|
|
2163
|
-
});
|
|
2164
|
-
}
|
|
2165
|
-
/**
|
|
2166
|
-
* Given two closed blueprints, find their intersection points, split each
|
|
2167
|
-
* blueprint's curves at those points, and pair up the resulting segments.
|
|
2168
|
-
*
|
|
2169
|
-
* Returns an array of paired segments (one from each blueprint) that share
|
|
2170
|
-
* the same start/end intersection points, or `null` if the blueprints do not
|
|
2171
|
-
* intersect.
|
|
2172
|
-
*/
|
|
2173
|
-
function blueprintsIntersectionSegments(first, second) {
|
|
2174
|
-
const { allIntersections: rawIntersections, allCommonSegments, firstCurvePoints, secondCurvePoints } = findAllIntersections(first, second);
|
|
2175
|
-
if (rawIntersections.length <= 1) return null;
|
|
2176
|
-
let firstCurveSegments = splitCurvesAtIntersections(first.curves, firstCurvePoints);
|
|
2177
|
-
let secondCurveSegments = splitCurvesAtIntersections(second.curves, secondCurvePoints);
|
|
2178
|
-
const commonSegmentsPoints = allCommonSegments.map((c) => [c.firstPoint, c.lastPoint]);
|
|
2179
|
-
const allIntersections = removeNonCrossingPoints(removeNonCrossingPoints(rawIntersections, firstCurveSegments, second), secondCurveSegments, first);
|
|
2180
|
-
if (allIntersections.length === 0 && allCommonSegments.length === 0) return null;
|
|
2181
|
-
if (allCommonSegments.length === 0) {
|
|
2182
|
-
const startAt = allIntersections[0];
|
|
2183
|
-
if (startAt === void 0) return null;
|
|
2184
|
-
firstCurveSegments = rotateToStartAt(firstCurveSegments, startAt);
|
|
2185
|
-
secondCurveSegments = rotateToStartAt(secondCurveSegments, startAt);
|
|
2186
|
-
} else {
|
|
2187
|
-
const startSegment = allCommonSegments[0];
|
|
2188
|
-
if (startSegment === void 0) return null;
|
|
2189
|
-
firstCurveSegments = rotateToStartAtSegment(firstCurveSegments, startSegment);
|
|
2190
|
-
secondCurveSegments = rotateToStartAtSegment(secondCurveSegments, startSegment);
|
|
2191
|
-
}
|
|
2192
|
-
const firstIntersectedSegments = Array.from(createSegmentOnPoints(firstCurveSegments, allIntersections, allCommonSegments));
|
|
2193
|
-
let secondIntersectedSegments = Array.from(createSegmentOnPoints(secondCurveSegments, allIntersections, allCommonSegments));
|
|
2194
|
-
const firstSeg = firstIntersectedSegments[0];
|
|
2195
|
-
const secondSeg = secondIntersectedSegments[0];
|
|
2196
|
-
if (firstSeg !== void 0 && secondSeg !== void 0) {
|
|
2197
|
-
const endpointsMismatch = !samePoint(endOfSegment(secondSeg), endOfSegment(firstSeg));
|
|
2198
|
-
const commonSegmentLengthMismatch = allCommonSegments.length > 0 && secondSeg.length !== 1;
|
|
2199
|
-
if (endpointsMismatch || commonSegmentLengthMismatch) secondIntersectedSegments = reverseSegments(secondIntersectedSegments);
|
|
2200
|
-
}
|
|
2201
|
-
const maxLen = Math.max(firstIntersectedSegments.length, secondIntersectedSegments.length);
|
|
2202
|
-
const result = [];
|
|
2203
|
-
for (let i = 0; i < maxLen; i++) {
|
|
2204
|
-
const firstSeg2 = firstIntersectedSegments[i];
|
|
2205
|
-
const secondSeg2 = secondIntersectedSegments[i];
|
|
2206
|
-
if (firstSeg2 === void 0 || secondSeg2 === void 0) {
|
|
2207
|
-
const available = firstSeg2 ?? secondSeg2;
|
|
2208
|
-
if (available === void 0) continue;
|
|
2209
|
-
result.push([available, available]);
|
|
2210
|
-
continue;
|
|
2211
|
-
}
|
|
2212
|
-
if (isCommonSegmentMatch(commonSegmentsPoints, startOfSegment(firstSeg2), endOfSegment(firstSeg2))) result.push([firstSeg2, "same"]);
|
|
2213
|
-
else result.push([firstSeg2, secondSeg2]);
|
|
2214
|
-
}
|
|
2215
|
-
return result;
|
|
2216
|
-
}
|
|
2217
|
-
//#endregion
|
|
2218
|
-
//#region src/2d/blueprints/segmentAssembly.ts
|
|
2219
|
-
/**
|
|
2220
|
-
* Merge adjacent collinear line segments into single segments.
|
|
2221
|
-
*
|
|
2222
|
-
* Boolean operations can split a line at intersection points that lie on the
|
|
2223
|
-
* line itself (e.g. when a cut rectangle's edge is collinear with the
|
|
2224
|
-
* profile's edge). The extra split creates a C0 discontinuity in swept
|
|
2225
|
-
* surfaces. Merging eliminates unnecessary vertices.
|
|
2226
|
-
*/
|
|
2227
|
-
function mergeCollinearSegments(curves) {
|
|
2228
|
-
if (curves.length < 2) return curves;
|
|
2229
|
-
const result = [];
|
|
2230
|
-
let i = 0;
|
|
2231
|
-
while (i < curves.length) {
|
|
2232
|
-
const current = wasmIndex(curves, i);
|
|
2233
|
-
if (current.geomType !== "LINE") {
|
|
2234
|
-
result.push(current);
|
|
2235
|
-
i++;
|
|
2236
|
-
continue;
|
|
2237
|
-
}
|
|
2238
|
-
let endPoint = current.lastPoint;
|
|
2239
|
-
let j = i + 1;
|
|
2240
|
-
while (j < curves.length) {
|
|
2241
|
-
const next = wasmIndex(curves, j);
|
|
2242
|
-
if (next.geomType !== "LINE") break;
|
|
2243
|
-
if (!samePoint(endPoint, next.firstPoint)) break;
|
|
2244
|
-
const dir1 = subtract2d(endPoint, current.firstPoint);
|
|
2245
|
-
const dir2 = subtract2d(next.lastPoint, next.firstPoint);
|
|
2246
|
-
if (Math.abs(crossProduct2d(dir1, dir2)) > 1e-9) break;
|
|
2247
|
-
endPoint = next.lastPoint;
|
|
2248
|
-
j++;
|
|
2249
|
-
}
|
|
2250
|
-
if (j > i + 1) result.push(make2dSegmentCurve(current.firstPoint, endPoint));
|
|
2251
|
-
else result.push(current);
|
|
2252
|
-
i = j;
|
|
2253
|
-
}
|
|
2254
|
-
return result;
|
|
2255
|
-
}
|
|
2256
|
-
/**
|
|
2257
|
-
* Split an array of curves into separate continuous paths. A discontinuity
|
|
2258
|
-
* occurs where one curve's lastPoint does not match the next curve's
|
|
2259
|
-
* firstPoint.
|
|
2260
|
-
*/
|
|
2261
|
-
function splitPaths(curves) {
|
|
2262
|
-
const startPoints = curves.map((c) => c.firstPoint);
|
|
2263
|
-
const shiftedEndPoints = curves.map((c) => c.lastPoint);
|
|
2264
|
-
const discontinuities = zip([startPoints, shiftedEndPoints.slice(-1).concat(shiftedEndPoints.slice(0, -1))]).map(([startPoint, endPoint], index) => {
|
|
2265
|
-
if (startPoint === void 0 || endPoint === void 0) return null;
|
|
2266
|
-
return samePoint(startPoint, endPoint) ? null : index;
|
|
2267
|
-
}).filter((f) => f !== null);
|
|
2268
|
-
if (discontinuities.length === 0) return [curves];
|
|
2269
|
-
const paths = zip([discontinuities.slice(0, -1), discontinuities.slice(1)]).map(([start, end]) => curves.slice(start, end));
|
|
2270
|
-
let lastPath = curves.slice(discontinuities[discontinuities.length - 1]);
|
|
2271
|
-
const firstDiscontinuity = discontinuities[0];
|
|
2272
|
-
if (firstDiscontinuity !== void 0 && firstDiscontinuity !== 0) lastPath = lastPath.concat(curves.slice(0, firstDiscontinuity));
|
|
2273
|
-
paths.push(lastPath);
|
|
2274
|
-
return paths;
|
|
2275
|
-
}
|
|
2276
|
-
/**
|
|
2277
|
-
* Handle the case where two segments overlap ("same"). The decision depends
|
|
2278
|
-
* on how many segments are entering the current intersection node.
|
|
2279
|
-
*/
|
|
2280
|
-
function handleSameSegment(firstSegment, segmentsIn, lastWasSame) {
|
|
2281
|
-
if (segmentsIn === 1) return {
|
|
2282
|
-
curves: [...firstSegment],
|
|
2283
|
-
segmentsIn: 1,
|
|
2284
|
-
lastWasSame: null
|
|
2285
|
-
};
|
|
2286
|
-
if (segmentsIn === 2 || segmentsIn === 0) return {
|
|
2287
|
-
curves: [],
|
|
2288
|
-
segmentsIn: null,
|
|
2289
|
-
lastWasSame: null
|
|
2290
|
-
};
|
|
2291
|
-
if (segmentsIn === null) return {
|
|
2292
|
-
curves: [],
|
|
2293
|
-
segmentsIn: null,
|
|
2294
|
-
lastWasSame: lastWasSame ? [...lastWasSame, ...firstSegment] : firstSegment
|
|
2295
|
-
};
|
|
2296
|
-
return {
|
|
2297
|
-
curves: [],
|
|
2298
|
-
segmentsIn,
|
|
2299
|
-
lastWasSame
|
|
2300
|
-
};
|
|
2301
|
-
}
|
|
2302
|
-
/**
|
|
2303
|
-
* Determine which non-overlapping segments to keep based on
|
|
2304
|
-
* inside/outside status relative to the other blueprint.
|
|
2305
|
-
*/
|
|
2306
|
-
function selectSegments(firstSegment, secondSegment, first, second, config, segmentsIn, lastWasSame) {
|
|
2307
|
-
let segments = [];
|
|
2308
|
-
let segmentsOut = 0;
|
|
2309
|
-
const firstCurve = firstSegment[0];
|
|
2310
|
-
if (firstCurve !== void 0) {
|
|
2311
|
-
const firstSegmentPoint = curveMidPoint(firstCurve);
|
|
2312
|
-
const firstInSecond = second.isInside(firstSegmentPoint);
|
|
2313
|
-
if (config.firstInside === "keep" && firstInSecond || config.firstInside === "remove" && !firstInSecond) {
|
|
2314
|
-
segmentsOut += 1;
|
|
2315
|
-
segments.push(...firstSegment);
|
|
2316
|
-
}
|
|
2317
|
-
}
|
|
2318
|
-
const secondCurve = secondSegment[0];
|
|
2319
|
-
if (secondCurve !== void 0) {
|
|
2320
|
-
const secondSegmentPoint = curveMidPoint(secondCurve);
|
|
2321
|
-
const secondInFirst = first.isInside(secondSegmentPoint);
|
|
2322
|
-
if (config.secondInside === "keep" && secondInFirst || config.secondInside === "remove" && !secondInFirst) {
|
|
2323
|
-
let segmentsToAdd = secondSegment;
|
|
2324
|
-
if (segmentsOut === 1) segmentsToAdd = reverseSegment(secondSegment);
|
|
2325
|
-
segmentsOut += 1;
|
|
2326
|
-
segments.push(...segmentsToAdd);
|
|
2327
|
-
}
|
|
2328
|
-
}
|
|
2329
|
-
if (segmentsIn === null && segmentsOut === 1 && lastWasSame !== null) segments = [...lastWasSame, ...segments];
|
|
2330
|
-
return {
|
|
2331
|
-
curves: segments,
|
|
2332
|
-
segmentsIn: segmentsOut === 1 ? segmentsOut : segmentsIn,
|
|
2333
|
-
lastWasSame: segmentsOut === 1 ? null : lastWasSame
|
|
2334
|
-
};
|
|
2335
|
-
}
|
|
2336
|
-
/**
|
|
2337
|
-
* Core boolean operation between two simple (non-compound) blueprints.
|
|
2338
|
-
*
|
|
2339
|
-
* Segments both blueprints at their intersection points, then selects which
|
|
2340
|
-
* segments to keep based on the `firstInside`/`secondInside` configuration.
|
|
2341
|
-
*/
|
|
2342
|
-
function booleanOperation(first, second, config) {
|
|
2343
|
-
const segments = blueprintsIntersectionSegments(first, second);
|
|
2344
|
-
if (segments === null) return buildNoIntersectionResult(first, second);
|
|
2345
|
-
if (segments.every(([, secondSegment]) => secondSegment === "same")) return { identical: true };
|
|
2346
|
-
let segmentsIn = null;
|
|
2347
|
-
let lastWasSame = null;
|
|
2348
|
-
let assembledCurves = segments.flatMap(([firstSegment, secondSegment]) => {
|
|
2349
|
-
if (secondSegment === "same") {
|
|
2350
|
-
const result = handleSameSegment(firstSegment, segmentsIn, lastWasSame);
|
|
2351
|
-
segmentsIn = result.segmentsIn;
|
|
2352
|
-
lastWasSame = result.lastWasSame;
|
|
2353
|
-
return result.curves;
|
|
2354
|
-
}
|
|
2355
|
-
const result = selectSegments(firstSegment, secondSegment, first, second, config, segmentsIn, lastWasSame);
|
|
2356
|
-
segmentsIn = result.segmentsIn;
|
|
2357
|
-
lastWasSame = result.lastWasSame;
|
|
2358
|
-
return result.curves;
|
|
2359
|
-
});
|
|
2360
|
-
const finalLastWasSame = lastWasSame;
|
|
2361
|
-
if (finalLastWasSame !== null && segmentsIn === 1) assembledCurves = [...finalLastWasSame, ...assembledCurves];
|
|
2362
|
-
const paths = splitPaths(mergeCollinearSegments(assembledCurves)).filter((b) => b.length > 0).map((b) => new Blueprint(b));
|
|
2363
|
-
if (paths.length === 0) return null;
|
|
2364
|
-
if (paths.length === 1) {
|
|
2365
|
-
const single = paths[0];
|
|
2366
|
-
if (single === void 0) return null;
|
|
2367
|
-
return single;
|
|
2368
|
-
}
|
|
2369
|
-
return organiseBlueprints(paths);
|
|
2370
|
-
}
|
|
2371
|
-
function buildNoIntersectionResult(first, second) {
|
|
2372
|
-
const firstCurve = first.curves[0];
|
|
2373
|
-
const secondCurve = second.curves[0];
|
|
2374
|
-
return {
|
|
2375
|
-
identical: false,
|
|
2376
|
-
firstCurveInSecond: firstCurve !== void 0 && second.isInside(curveMidPoint(firstCurve)),
|
|
2377
|
-
secondCurveInFirst: secondCurve !== void 0 && first.isInside(curveMidPoint(secondCurve))
|
|
2378
|
-
};
|
|
2379
|
-
}
|
|
2380
|
-
//#endregion
|
|
2381
|
-
//#region src/2d/blueprints/booleanOperations.ts
|
|
2382
|
-
/**
|
|
2383
|
-
* Boolean operations on 2D blueprints: fuse, cut, and intersect.
|
|
2384
|
-
*
|
|
2385
|
-
* This module is the public API. Internal logic is split across:
|
|
2386
|
-
* - `booleanHelpers.ts` — hashing, segment types, rotation utilities
|
|
2387
|
-
* - `intersectionSegments.ts` — curve intersection and segment pairing
|
|
2388
|
-
* - `segmentAssembly.ts` — segment selection and path assembly
|
|
2389
|
-
*/
|
|
2390
|
-
/**
|
|
2391
|
-
* Compute the boolean union of two simple blueprints.
|
|
2392
|
-
*
|
|
2393
|
-
* Segments each blueprint at their intersection points, discards segments
|
|
2394
|
-
* inside the other shape, and reassembles the remaining curves.
|
|
2395
|
-
*
|
|
2396
|
-
* @param first - First blueprint operand.
|
|
2397
|
-
* @param second - Second blueprint operand.
|
|
2398
|
-
* @returns The fused outline, a {@link Blueprints} if the result is
|
|
2399
|
-
* disjoint, or `null` if the operation produces no geometry.
|
|
2400
|
-
*
|
|
2401
|
-
* @remarks Both blueprints must be closed. For compound or multi-blueprint
|
|
2402
|
-
* inputs, use {@link fuse2D} instead.
|
|
2403
|
-
*/
|
|
2404
|
-
function fuseBlueprints(first, second) {
|
|
2405
|
-
const result = booleanOperation(first, second, {
|
|
2406
|
-
firstInside: "remove",
|
|
2407
|
-
secondInside: "remove"
|
|
2408
|
-
});
|
|
2409
|
-
if (result === null || result instanceof Blueprint || result instanceof Blueprints) return result;
|
|
2410
|
-
if (result.identical) return first.clone();
|
|
2411
|
-
if (result.firstCurveInSecond) return second.clone();
|
|
2412
|
-
if (result.secondCurveInFirst) return first.clone();
|
|
2413
|
-
return new Blueprints([first, second]);
|
|
2414
|
-
}
|
|
2415
|
-
/**
|
|
2416
|
-
* Compute the boolean difference of two simple blueprints (first minus second).
|
|
2417
|
-
*
|
|
2418
|
-
* Segments the blueprints at their intersections, keeps segments of the first
|
|
2419
|
-
* that are outside the second, and segments of the second that are inside the
|
|
2420
|
-
* first (reversed to form the boundary of the cut).
|
|
2421
|
-
*
|
|
2422
|
-
* @param first - Base blueprint to cut from.
|
|
2423
|
-
* @param second - Tool blueprint to subtract.
|
|
2424
|
-
* @returns The remaining outline, or `null` if nothing remains.
|
|
2425
|
-
*
|
|
2426
|
-
* @remarks Both blueprints must be closed. For compound inputs use {@link cut2D}.
|
|
2427
|
-
*/
|
|
2428
|
-
function cutBlueprints(first, second) {
|
|
2429
|
-
const result = booleanOperation(first, second, {
|
|
2430
|
-
firstInside: "remove",
|
|
2431
|
-
secondInside: "keep"
|
|
2432
|
-
});
|
|
2433
|
-
if (result === null || result instanceof Blueprint || result instanceof Blueprints) return result;
|
|
2434
|
-
if (result.identical) return null;
|
|
2435
|
-
if (result.firstCurveInSecond) return null;
|
|
2436
|
-
if (result.secondCurveInFirst) return new Blueprints([new CompoundBlueprint([first, second])]);
|
|
2437
|
-
return first.clone();
|
|
2438
|
-
}
|
|
2439
|
-
/**
|
|
2440
|
-
* Compute the boolean intersection of two simple blueprints.
|
|
2441
|
-
*
|
|
2442
|
-
* Keeps only the segments of each blueprint that lie inside the other,
|
|
2443
|
-
* producing the overlapping region.
|
|
2444
|
-
*
|
|
2445
|
-
* @param first - First blueprint operand.
|
|
2446
|
-
* @param second - Second blueprint operand.
|
|
2447
|
-
* @returns The intersection outline, or `null` if the blueprints do not overlap.
|
|
2448
|
-
*
|
|
2449
|
-
* @remarks Both blueprints must be closed. For compound inputs use {@link intersect2D}.
|
|
2450
|
-
*/
|
|
2451
|
-
function intersectBlueprints(first, second) {
|
|
2452
|
-
const result = booleanOperation(first, second, {
|
|
2453
|
-
firstInside: "keep",
|
|
2454
|
-
secondInside: "keep"
|
|
2455
|
-
});
|
|
2456
|
-
if (result === null || result instanceof Blueprint || result instanceof Blueprints) return result;
|
|
2457
|
-
if (result.identical) return first.clone();
|
|
2458
|
-
if (result.firstCurveInSecond) return first.clone();
|
|
2459
|
-
if (result.secondCurveInFirst) return second.clone();
|
|
2460
|
-
return null;
|
|
2461
|
-
}
|
|
2462
|
-
//#endregion
|
|
2463
|
-
//#region src/2d/blueprints/boolean2D.ts
|
|
2464
|
-
var genericIntersects = (first, second) => {
|
|
2465
|
-
if (first instanceof Blueprint && second instanceof Blueprint) {
|
|
2466
|
-
let allIntersections = [];
|
|
2467
|
-
first.curves.forEach((thisCurve) => {
|
|
2468
|
-
second.curves.forEach((otherCurve) => {
|
|
2469
|
-
const { intersections, commonSegmentsPoints } = unwrap(intersectCurves(thisCurve, otherCurve));
|
|
2470
|
-
allIntersections.push(...intersections);
|
|
2471
|
-
allIntersections.push(...commonSegmentsPoints);
|
|
2472
|
-
});
|
|
2473
|
-
});
|
|
2474
|
-
allIntersections = removeDuplicatePoints(allIntersections);
|
|
2475
|
-
return allIntersections.length > 1;
|
|
2476
|
-
}
|
|
2477
|
-
if (first instanceof CompoundBlueprint || first instanceof Blueprints) return first.blueprints.some((bp) => genericIntersects(bp, second));
|
|
2478
|
-
if (second instanceof CompoundBlueprint || second instanceof Blueprints) return second.blueprints.some((bp) => genericIntersects(first, bp));
|
|
2479
|
-
bug("genericIntersects", "Unhandled shape combination in genericIntersects");
|
|
2480
|
-
};
|
|
2481
|
-
var genericFuse = (first, second) => {
|
|
2482
|
-
if (first instanceof CompoundBlueprint) {
|
|
2483
|
-
if (second instanceof Blueprint) return fuseBlueprintWithCompound(second, first);
|
|
2484
|
-
if (second instanceof CompoundBlueprint) return fuseCompoundWithCompound(first, second);
|
|
2485
|
-
}
|
|
2486
|
-
if (second instanceof CompoundBlueprint) {
|
|
2487
|
-
if (first instanceof Blueprint) return fuseBlueprintWithCompound(first, second);
|
|
2488
|
-
if (first instanceof CompoundBlueprint) return fuseCompoundWithCompound(first, second);
|
|
2489
|
-
}
|
|
2490
|
-
if (first instanceof Blueprint && second instanceof Blueprint) return fuseBlueprints(first, second);
|
|
2491
|
-
bug("genericFuse", "Unhandled shape combination in genericFuse");
|
|
2492
|
-
};
|
|
2493
|
-
var fuseIntersectingBlueprints = (blueprints) => {
|
|
2494
|
-
const fused = /* @__PURE__ */ new Map();
|
|
2495
|
-
const output = [];
|
|
2496
|
-
blueprints.forEach((inputBlueprint, i) => {
|
|
2497
|
-
let savedBlueprint;
|
|
2498
|
-
if (fused.has(i)) savedBlueprint = fused.get(i);
|
|
2499
|
-
else {
|
|
2500
|
-
savedBlueprint = {
|
|
2501
|
-
current: inputBlueprint,
|
|
2502
|
-
fusedWith: new Set([i])
|
|
2503
|
-
};
|
|
2504
|
-
output.push(savedBlueprint);
|
|
2505
|
-
}
|
|
2506
|
-
blueprints.slice(i + 1).forEach((inputOtherBlueprint, j) => {
|
|
2507
|
-
const blueprint = savedBlueprint.current;
|
|
2508
|
-
const currentIndex = i + j + 1;
|
|
2509
|
-
if (savedBlueprint.fusedWith.has(currentIndex)) return;
|
|
2510
|
-
let otherBlueprint = inputOtherBlueprint;
|
|
2511
|
-
let otherIsFused = false;
|
|
2512
|
-
if (fused.has(currentIndex)) {
|
|
2513
|
-
otherBlueprint = fused.get(currentIndex).current;
|
|
2514
|
-
otherIsFused = true;
|
|
2515
|
-
}
|
|
2516
|
-
if (blueprint.boundingBox.isOut(otherBlueprint.boundingBox)) return;
|
|
2517
|
-
if (!genericIntersects(blueprint, otherBlueprint)) return;
|
|
2518
|
-
let newFused;
|
|
2519
|
-
if (blueprint instanceof Blueprints || otherBlueprint instanceof Blueprints) {
|
|
2520
|
-
const fused = fuse2D(blueprint, otherBlueprint);
|
|
2521
|
-
if (fused === null) bug("fuseIntersectingBlueprints", "fuse2D returned null for non-null inputs");
|
|
2522
|
-
newFused = fused;
|
|
2523
|
-
} else newFused = genericFuse(blueprint, otherBlueprint);
|
|
2524
|
-
if (!(newFused instanceof Blueprint || newFused instanceof CompoundBlueprint)) {
|
|
2525
|
-
if (newFused instanceof Blueprints && newFused.blueprints.length === 2) return;
|
|
2526
|
-
else if (newFused instanceof Blueprints && newFused.blueprints.length === 1) newFused = safeIndex(newFused.blueprints, 0, "fuseIntersectingBlueprints");
|
|
2527
|
-
else if (!(newFused instanceof Blueprints)) bug("fuseIntersectingBlueprints", "Fuse produced unexpected non-blueprint result");
|
|
2528
|
-
}
|
|
2529
|
-
savedBlueprint.fusedWith.add(currentIndex);
|
|
2530
|
-
savedBlueprint.current = newFused;
|
|
2531
|
-
if (!otherIsFused) fused.set(currentIndex, savedBlueprint);
|
|
2532
|
-
});
|
|
2533
|
-
});
|
|
2534
|
-
return organiseBlueprints(output.map(({ current }) => current).flatMap((b) => allBlueprints(b)));
|
|
2535
|
-
};
|
|
2536
|
-
var allBlueprints = (shape) => {
|
|
2537
|
-
if (shape instanceof Blueprint) return [shape];
|
|
2538
|
-
if (shape instanceof CompoundBlueprint) return shape.blueprints;
|
|
2539
|
-
if (shape instanceof Blueprints) return shape.blueprints.flatMap((b) => allBlueprints(b));
|
|
2540
|
-
return [];
|
|
2541
|
-
};
|
|
2542
|
-
var fuseBlueprintWithCompound = (blueprint, compound) => {
|
|
2543
|
-
const outerFused = fuseBlueprints(blueprint, safeIndex(compound.blueprints, 0, "fuseBlueprintWithCompound"));
|
|
2544
|
-
const innerFused = compound.blueprints.slice(1).map((c) => cutBlueprints(c, blueprint));
|
|
2545
|
-
return organiseBlueprints([...allBlueprints(outerFused), ...innerFused.flatMap((fused) => allBlueprints(fused))]);
|
|
2546
|
-
};
|
|
2547
|
-
function allPairs(list1, list2) {
|
|
2548
|
-
const result = [];
|
|
2549
|
-
for (const l1 of list1) for (const l2 of list2) result.push([l1, l2]);
|
|
2550
|
-
return result;
|
|
2551
|
-
}
|
|
2552
|
-
var fuseCompoundWithCompound = (first, second) => {
|
|
2553
|
-
const firstOuter = safeIndex(first.blueprints, 0, "fuseCompoundWithCompound");
|
|
2554
|
-
const secondOuter = safeIndex(second.blueprints, 0, "fuseCompoundWithCompound");
|
|
2555
|
-
const outerFused = fuseBlueprints(firstOuter, secondOuter);
|
|
2556
|
-
const inner1Fused = second.blueprints.slice(1).map((c) => cutBlueprints(c, firstOuter));
|
|
2557
|
-
const inner2Fused = first.blueprints.slice(1).map((c) => cutBlueprints(c, secondOuter));
|
|
2558
|
-
const innerIntersections = allPairs(first.blueprints.slice(1), second.blueprints.slice(1)).flatMap(([first, second]) => {
|
|
2559
|
-
return allBlueprints(intersectBlueprints(first, second));
|
|
2560
|
-
});
|
|
2561
|
-
return organiseBlueprints([
|
|
2562
|
-
...allBlueprints(outerFused),
|
|
2563
|
-
...inner1Fused.flatMap((fused) => allBlueprints(fused)),
|
|
2564
|
-
...inner2Fused.flatMap((fused) => allBlueprints(fused)),
|
|
2565
|
-
...innerIntersections
|
|
2566
|
-
]);
|
|
2567
|
-
};
|
|
2568
|
-
/**
|
|
2569
|
-
* Compute the boolean union of two 2D shapes.
|
|
2570
|
-
*
|
|
2571
|
-
* Handles all combinations of {@link Blueprint}, {@link CompoundBlueprint},
|
|
2572
|
-
* {@link Blueprints}, and `null`. When both inputs are simple blueprints the
|
|
2573
|
-
* operation delegates to {@link fuseBlueprints}; compound and multi-blueprint
|
|
2574
|
-
* cases are decomposed recursively.
|
|
2575
|
-
*
|
|
2576
|
-
* @param first - First operand (or `null` for empty).
|
|
2577
|
-
* @param second - Second operand (or `null` for empty).
|
|
2578
|
-
* @returns The fused shape, or `null` if both operands are empty.
|
|
2579
|
-
*
|
|
2580
|
-
* @example
|
|
2581
|
-
* ```ts
|
|
2582
|
-
* const union = fuse2D(circleBlueprint, squareBlueprint);
|
|
2583
|
-
* ```
|
|
2584
|
-
*
|
|
2585
|
-
* @see {@link fuse2D} for the functional API.
|
|
2586
|
-
*/
|
|
2587
|
-
var fuse2D = (first, second) => {
|
|
2588
|
-
if (first === null) return second?.clone() ?? null;
|
|
2589
|
-
if (second === null) return first.clone();
|
|
2590
|
-
if (!(first instanceof Blueprints) && second instanceof Blueprints) return fuseIntersectingBlueprints([first, ...second.blueprints]);
|
|
2591
|
-
if (!(second instanceof Blueprints) && first instanceof Blueprints) return fuseIntersectingBlueprints([second, ...first.blueprints]);
|
|
2592
|
-
if (first instanceof Blueprints && second instanceof Blueprints) {
|
|
2593
|
-
let out = fuse2D(safeIndex(first.blueprints, 0, "fuse2D"), second);
|
|
2594
|
-
first.blueprints.slice(1).forEach((bp) => {
|
|
2595
|
-
out = fuse2D(bp, out);
|
|
2596
|
-
});
|
|
2597
|
-
return out;
|
|
2598
|
-
}
|
|
2599
|
-
if (first instanceof CompoundBlueprint) {
|
|
2600
|
-
if (second instanceof Blueprints) return fuse2D(second, first);
|
|
2601
|
-
if (second instanceof Blueprint) return fuseBlueprintWithCompound(second, first);
|
|
2602
|
-
if (second instanceof CompoundBlueprint) return fuseCompoundWithCompound(first, second);
|
|
2603
|
-
}
|
|
2604
|
-
if (second instanceof CompoundBlueprint) {
|
|
2605
|
-
if (first instanceof Blueprints) return fuse2D(first, second);
|
|
2606
|
-
if (first instanceof Blueprint) return fuseBlueprintWithCompound(first, second);
|
|
2607
|
-
if (first instanceof CompoundBlueprint) return fuseCompoundWithCompound(first, second);
|
|
2608
|
-
}
|
|
2609
|
-
if (first instanceof Blueprint && second instanceof Blueprint) return fuseBlueprints(first, second);
|
|
2610
|
-
return null;
|
|
2611
|
-
};
|
|
2612
|
-
var mergeNonIntersecting = (shapes) => {
|
|
2613
|
-
const exploded = shapes.flatMap((s) => {
|
|
2614
|
-
if (s === null) return [];
|
|
2615
|
-
if (s instanceof Blueprints) return s.blueprints;
|
|
2616
|
-
return s;
|
|
2617
|
-
});
|
|
2618
|
-
if (exploded.length === 1) return safeIndex(exploded, 0, "mergeNonIntersecting");
|
|
2619
|
-
return new Blueprints(exploded);
|
|
2620
|
-
};
|
|
2621
|
-
/**
|
|
2622
|
-
* Compute the boolean difference of two 2D shapes (first minus second).
|
|
2623
|
-
*
|
|
2624
|
-
* Removes the region covered by `second` from `first`. When the tool is fully
|
|
2625
|
-
* inside the base, the result is a {@link CompoundBlueprint} (base with a
|
|
2626
|
-
* hole).
|
|
2627
|
-
*
|
|
2628
|
-
* @param first - Base shape to cut from.
|
|
2629
|
-
* @param second - Tool shape to subtract.
|
|
2630
|
-
* @returns The remaining shape, or `null` if nothing remains.
|
|
2631
|
-
*
|
|
2632
|
-
* @example
|
|
2633
|
-
* ```ts
|
|
2634
|
-
* const withHole = cut2D(outerRect, innerCircle);
|
|
2635
|
-
* ```
|
|
2636
|
-
*
|
|
2637
|
-
* @see {@link cut2D} for the functional API.
|
|
2638
|
-
*/
|
|
2639
|
-
var cut2D = (first, second) => {
|
|
2640
|
-
if (first === null) return null;
|
|
2641
|
-
if (second === null) return first.clone();
|
|
2642
|
-
if (first instanceof Blueprints) return mergeNonIntersecting(first.blueprints.map((bp) => cut2D(bp, second)));
|
|
2643
|
-
if (first instanceof CompoundBlueprint) {
|
|
2644
|
-
const wrapper = safeIndex(first.blueprints, 0, "cut2D");
|
|
2645
|
-
if (second instanceof Blueprint && !second.intersects(wrapper)) {
|
|
2646
|
-
if (!wrapper.isInside(second.firstPoint)) return first.clone();
|
|
2647
|
-
return organiseBlueprints([wrapper, ...allBlueprints(fuse2D(second, new Blueprints(first.blueprints.slice(1))))]);
|
|
2648
|
-
} else {
|
|
2649
|
-
let out = cut2D(wrapper, second);
|
|
2650
|
-
first.blueprints.slice(1).forEach((bp) => {
|
|
2651
|
-
out = cut2D(out, bp);
|
|
2652
|
-
});
|
|
2653
|
-
return out;
|
|
2654
|
-
}
|
|
2655
|
-
}
|
|
2656
|
-
if (second instanceof Blueprints) {
|
|
2657
|
-
let out = first;
|
|
2658
|
-
for (const bp of second.blueprints) out = cut2D(out, bp);
|
|
2659
|
-
return out;
|
|
2660
|
-
}
|
|
2661
|
-
if (second instanceof CompoundBlueprint) {
|
|
2662
|
-
let out = cutBlueprints(first, safeIndex(second.blueprints, 0, "cut2D"));
|
|
2663
|
-
second.blueprints.slice(1).forEach((bp) => {
|
|
2664
|
-
out = fuse2D(out, intersectBlueprints(bp, first));
|
|
2665
|
-
});
|
|
2666
|
-
return out;
|
|
2667
|
-
}
|
|
2668
|
-
return cutBlueprints(first, second);
|
|
2669
|
-
};
|
|
2670
|
-
/**
|
|
2671
|
-
* Compute the boolean intersection of two 2D shapes.
|
|
2672
|
-
*
|
|
2673
|
-
* Returns only the region common to both shapes. Compound and multi-blueprint
|
|
2674
|
-
* operands are decomposed recursively, with holes handled via complementary
|
|
2675
|
-
* cut operations.
|
|
2676
|
-
*
|
|
2677
|
-
* @param first - First operand.
|
|
2678
|
-
* @param second - Second operand.
|
|
2679
|
-
* @returns The intersection shape, or `null` if the shapes do not overlap.
|
|
2680
|
-
*
|
|
2681
|
-
* @example
|
|
2682
|
-
* ```ts
|
|
2683
|
-
* const overlap = intersect2D(circle, rectangle);
|
|
2684
|
-
* ```
|
|
2685
|
-
*
|
|
2686
|
-
* @see {@link intersect2D} for the functional API.
|
|
2687
|
-
*/
|
|
2688
|
-
function intersect2D(first, second) {
|
|
2689
|
-
if (first === null || second === null) return null;
|
|
2690
|
-
if (first instanceof Blueprint && second instanceof Blueprint) return intersectBlueprints(first, second);
|
|
2691
|
-
if (first instanceof Blueprints) return mergeNonIntersecting(first.blueprints.map((bp) => intersect2D(bp, second)));
|
|
2692
|
-
if (first instanceof CompoundBlueprint) {
|
|
2693
|
-
const wrapper = safeIndex(first.blueprints, 0, "intersect2D");
|
|
2694
|
-
const cuts = first.blueprints.slice(1);
|
|
2695
|
-
if (cuts.length === 0) return intersect2D(wrapper, second);
|
|
2696
|
-
let result = intersect2D(wrapper, second);
|
|
2697
|
-
for (const cut of cuts) result = cut2D(result, cut);
|
|
2698
|
-
return result;
|
|
2699
|
-
}
|
|
2700
|
-
if (second instanceof Blueprints) return mergeNonIntersecting(second.blueprints.map((bp) => intersect2D(first, bp)));
|
|
2701
|
-
if (second instanceof CompoundBlueprint) {
|
|
2702
|
-
const wrapper = safeIndex(second.blueprints, 0, "intersect2D");
|
|
2703
|
-
const cuts = second.blueprints.slice(1);
|
|
2704
|
-
if (cuts.length === 0) return intersect2D(wrapper, first);
|
|
2705
|
-
let result = intersect2D(wrapper, first);
|
|
2706
|
-
for (const cut of cuts) result = cut2D(result, cut);
|
|
2707
|
-
return result;
|
|
2708
|
-
}
|
|
2709
|
-
bug("intersect2D", "Unhandled Shape2D combination");
|
|
2710
|
-
}
|
|
2711
|
-
//#endregion
|
|
2712
|
-
export { Flatbush as S, Blueprints as _, fuseBlueprints as a, make2dOffset as b, roundedRectangleBlueprint as c, FaceSketcher as d, Sketch as f, CompoundBlueprint as g, organiseBlueprints as h, cutBlueprints as i, BaseSketcher2d as l, loftAll as m, fuse2D as n, intersectBlueprints as o, loft as p, intersect2D as r, polysidesBlueprint as s, cut2D as t, BlueprintSketcher as u, chamferCurves as v, intersectCurves as x, filletCurves as y };
|
|
1464
|
+
export { Blueprints as a, make2dOffset as c, CompoundBlueprint as i, intersectCurves as l, BaseSketcher2d as n, chamferCurves as o, organiseBlueprints as r, filletCurves as s, BlueprintSketcher as t, Flatbush as u };
|