brep-io-kernel 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +32 -0
- package/README.md +144 -0
- package/dist-kernel/brep-kernel.js +74699 -0
- package/dist-kernel/help/CONTRIBUTING.html +248 -0
- package/dist-kernel/help/LICENSE.html +248 -0
- package/dist-kernel/help/MODELING.png +0 -0
- package/dist-kernel/help/PMI.png +0 -0
- package/dist-kernel/help/SKETCH.png +0 -0
- package/dist-kernel/help/assembly-constraints__Coincident_Constraint_dialog.png +0 -0
- package/dist-kernel/help/assembly-constraints___Angle_Constraint_dialog.png +0 -0
- package/dist-kernel/help/assembly-constraints___Distance_Constraint_dialog.png +0 -0
- package/dist-kernel/help/assembly-constraints___Fixed_Constraint_dialog.png +0 -0
- package/dist-kernel/help/assembly-constraints___Parallel_Constraint_dialog.png +0 -0
- package/dist-kernel/help/assembly-constraints___Touch_Align_Constraint_dialog.png +0 -0
- package/dist-kernel/help/assembly-constraints__angle-constraint.html +248 -0
- package/dist-kernel/help/assembly-constraints__coincident-constraint.html +248 -0
- package/dist-kernel/help/assembly-constraints__distance-constraint.html +248 -0
- package/dist-kernel/help/assembly-constraints__fixed-constraint.html +248 -0
- package/dist-kernel/help/assembly-constraints__parallel-constraint.html +248 -0
- package/dist-kernel/help/assembly-constraints__solver.html +248 -0
- package/dist-kernel/help/assembly-constraints__touch-align-constraint.html +248 -0
- package/dist-kernel/help/brep-api.html +263 -0
- package/dist-kernel/help/brep-kernel.html +258 -0
- package/dist-kernel/help/brep-model.html +248 -0
- package/dist-kernel/help/cylindrical-face-radius-embedding.html +290 -0
- package/dist-kernel/help/dialog-screenshots.html +248 -0
- package/dist-kernel/help/extruded-sketch-radius-embedding.html +336 -0
- package/dist-kernel/help/features__Assembly_Component_dialog.png +0 -0
- package/dist-kernel/help/features__Boolean_dialog.png +0 -0
- package/dist-kernel/help/features__Chamfer_dialog.png +0 -0
- package/dist-kernel/help/features__Datium_dialog.png +0 -0
- package/dist-kernel/help/features__Extrude_dialog.png +0 -0
- package/dist-kernel/help/features__Fillet_dialog.png +0 -0
- package/dist-kernel/help/features__Helix_dialog.png +0 -0
- package/dist-kernel/help/features__Hole_dialog.png +0 -0
- package/dist-kernel/help/features__Image_Heightmap_Solid_dialog.png +0 -0
- package/dist-kernel/help/features__Image_to_Face_dialog.png +0 -0
- package/dist-kernel/help/features__Import_3D_Model_dialog.png +0 -0
- package/dist-kernel/help/features__Loft_dialog.png +0 -0
- package/dist-kernel/help/features__Mirror_dialog.png +0 -0
- package/dist-kernel/help/features__Offset_Shell_dialog.png +0 -0
- package/dist-kernel/help/features__Overlap_Cleanup_dialog.png +0 -0
- package/dist-kernel/help/features__Pattern_Linear_dialog.png +0 -0
- package/dist-kernel/help/features__Pattern_Radial_dialog.png +0 -0
- package/dist-kernel/help/features__Pattern_dialog.png +0 -0
- package/dist-kernel/help/features__Plane_dialog.png +0 -0
- package/dist-kernel/help/features__Primitive_Cone_dialog.png +0 -0
- package/dist-kernel/help/features__Primitive_Cube_dialog.png +0 -0
- package/dist-kernel/help/features__Primitive_Cylinder_dialog.png +0 -0
- package/dist-kernel/help/features__Primitive_Pyramid_dialog.png +0 -0
- package/dist-kernel/help/features__Primitive_Sphere_dialog.png +0 -0
- package/dist-kernel/help/features__Primitive_Torus_dialog.png +0 -0
- package/dist-kernel/help/features__Remesh_dialog.png +0 -0
- package/dist-kernel/help/features__Revolve_dialog.png +0 -0
- package/dist-kernel/help/features__Sheet_Metal_Contour_Flange_dialog.png +0 -0
- package/dist-kernel/help/features__Sheet_Metal_Cutout_dialog.png +0 -0
- package/dist-kernel/help/features__Sheet_Metal_Flange_dialog.png +0 -0
- package/dist-kernel/help/features__Sheet_Metal_Tab_dialog.png +0 -0
- package/dist-kernel/help/features__Sketch_dialog.png +0 -0
- package/dist-kernel/help/features__Spline_dialog.png +0 -0
- package/dist-kernel/help/features__Sweep_dialog.png +0 -0
- package/dist-kernel/help/features__Transform_dialog.png +0 -0
- package/dist-kernel/help/features__Tube_dialog.png +0 -0
- package/dist-kernel/help/features__assembly-component.html +248 -0
- package/dist-kernel/help/features__boolean.html +248 -0
- package/dist-kernel/help/features__chamfer.html +248 -0
- package/dist-kernel/help/features__datium.html +248 -0
- package/dist-kernel/help/features__datum.html +248 -0
- package/dist-kernel/help/features__extrude.html +248 -0
- package/dist-kernel/help/features__fillet.html +248 -0
- package/dist-kernel/help/features__helix.html +248 -0
- package/dist-kernel/help/features__hole.html +248 -0
- package/dist-kernel/help/features__image-heightmap-solid.html +248 -0
- package/dist-kernel/help/features__image-to-face-2D_dialog.png +0 -0
- package/dist-kernel/help/features__image-to-face-3D_dialog.png +0 -0
- package/dist-kernel/help/features__image-to-face.html +248 -0
- package/dist-kernel/help/features__import-3d-model.html +248 -0
- package/dist-kernel/help/features__index.html +248 -0
- package/dist-kernel/help/features__loft.html +248 -0
- package/dist-kernel/help/features__mirror.html +248 -0
- package/dist-kernel/help/features__offset-shell.html +248 -0
- package/dist-kernel/help/features__pattern-linear.html +248 -0
- package/dist-kernel/help/features__pattern-radial.html +248 -0
- package/dist-kernel/help/features__pattern.html +248 -0
- package/dist-kernel/help/features__plane.html +248 -0
- package/dist-kernel/help/features__primitive-cone.html +248 -0
- package/dist-kernel/help/features__primitive-cube.html +248 -0
- package/dist-kernel/help/features__primitive-cylinder.html +248 -0
- package/dist-kernel/help/features__primitive-pyramid.html +248 -0
- package/dist-kernel/help/features__primitive-sphere.html +248 -0
- package/dist-kernel/help/features__primitive-torus.html +248 -0
- package/dist-kernel/help/features__remesh.html +248 -0
- package/dist-kernel/help/features__revolve.html +248 -0
- package/dist-kernel/help/features__sheet-metal-contour-flange.html +248 -0
- package/dist-kernel/help/features__sheet-metal-flange.html +248 -0
- package/dist-kernel/help/features__sheet-metal-tab.html +248 -0
- package/dist-kernel/help/features__sketch.html +248 -0
- package/dist-kernel/help/features__spline.html +248 -0
- package/dist-kernel/help/features__sweep.html +248 -0
- package/dist-kernel/help/features__transform.html +248 -0
- package/dist-kernel/help/features__tube.html +248 -0
- package/dist-kernel/help/file-formats.html +248 -0
- package/dist-kernel/help/getting-started.html +248 -0
- package/dist-kernel/help/highlights.html +248 -0
- package/dist-kernel/help/history-systems.html +248 -0
- package/dist-kernel/help/how-it-works.html +248 -0
- package/dist-kernel/help/index.html +862 -0
- package/dist-kernel/help/input-params-schema.html +363 -0
- package/dist-kernel/help/inspector-improvements.html +248 -0
- package/dist-kernel/help/inspector.html +248 -0
- package/dist-kernel/help/modes__modeling.html +248 -0
- package/dist-kernel/help/modes__pmi.html +248 -0
- package/dist-kernel/help/modes__sketch.html +248 -0
- package/dist-kernel/help/plugins.html +248 -0
- package/dist-kernel/help/pmi-annotations__Angle_Dimension_dialog.png +0 -0
- package/dist-kernel/help/pmi-annotations__Explode_Body_dialog.png +0 -0
- package/dist-kernel/help/pmi-annotations__Hole_Callout_dialog.png +0 -0
- package/dist-kernel/help/pmi-annotations__Leader_dialog.png +0 -0
- package/dist-kernel/help/pmi-annotations__Linear_Dimension_dialog.png +0 -0
- package/dist-kernel/help/pmi-annotations__Note_dialog.png +0 -0
- package/dist-kernel/help/pmi-annotations__Radial_Dimension_dialog.png +0 -0
- package/dist-kernel/help/pmi-annotations__angle-dimension.html +248 -0
- package/dist-kernel/help/pmi-annotations__explode-body.html +248 -0
- package/dist-kernel/help/pmi-annotations__hole-callout.html +248 -0
- package/dist-kernel/help/pmi-annotations__index.html +248 -0
- package/dist-kernel/help/pmi-annotations__leader.html +248 -0
- package/dist-kernel/help/pmi-annotations__linear-dimension.html +248 -0
- package/dist-kernel/help/pmi-annotations__note.html +248 -0
- package/dist-kernel/help/pmi-annotations__radial-dimension.html +248 -0
- package/dist-kernel/help/search-index.json +464 -0
- package/dist-kernel/help/simplified-radial-dimensions.html +298 -0
- package/dist-kernel/help/solid-methods.html +359 -0
- package/dist-kernel/help/table-of-contents.html +330 -0
- package/dist-kernel/help/ui-overview.html +248 -0
- package/dist-kernel/help/whats-new.html +248 -0
- package/package.json +54 -0
- package/src/BREP/AssemblyComponent.js +42 -0
- package/src/BREP/BREP.js +43 -0
- package/src/BREP/BetterSolid.js +805 -0
- package/src/BREP/Edge.js +103 -0
- package/src/BREP/Extrude.js +403 -0
- package/src/BREP/Face.js +187 -0
- package/src/BREP/MeshRepairer.js +634 -0
- package/src/BREP/OffsetShellSolid.js +614 -0
- package/src/BREP/PointCloudWrap.js +302 -0
- package/src/BREP/Revolve.js +345 -0
- package/src/BREP/SolidMethods/authoring.js +112 -0
- package/src/BREP/SolidMethods/booleanOps.js +230 -0
- package/src/BREP/SolidMethods/chamfer.js +122 -0
- package/src/BREP/SolidMethods/edgeResolution.js +25 -0
- package/src/BREP/SolidMethods/fillet.js +792 -0
- package/src/BREP/SolidMethods/index.js +72 -0
- package/src/BREP/SolidMethods/io.js +105 -0
- package/src/BREP/SolidMethods/lifecycle.js +103 -0
- package/src/BREP/SolidMethods/manifoldOps.js +375 -0
- package/src/BREP/SolidMethods/meshCleanup.js +2512 -0
- package/src/BREP/SolidMethods/meshQueries.js +264 -0
- package/src/BREP/SolidMethods/metadata.js +106 -0
- package/src/BREP/SolidMethods/metrics.js +51 -0
- package/src/BREP/SolidMethods/transforms.js +361 -0
- package/src/BREP/SolidMethods/visualize.js +508 -0
- package/src/BREP/SolidShared.js +26 -0
- package/src/BREP/Sweep.js +1596 -0
- package/src/BREP/Tube.js +857 -0
- package/src/BREP/Vertex.js +43 -0
- package/src/BREP/applyBooleanOperation.js +704 -0
- package/src/BREP/boundsUtils.js +48 -0
- package/src/BREP/chamfer.js +551 -0
- package/src/BREP/edgePolylineUtils.js +85 -0
- package/src/BREP/fillets/common.js +388 -0
- package/src/BREP/fillets/fillet.js +1422 -0
- package/src/BREP/fillets/filletGeometry.js +15 -0
- package/src/BREP/fillets/inset.js +389 -0
- package/src/BREP/fillets/offsetHelper.js +143 -0
- package/src/BREP/fillets/outset.js +88 -0
- package/src/BREP/helix.js +193 -0
- package/src/BREP/meshToBrep.js +234 -0
- package/src/BREP/primitives.js +279 -0
- package/src/BREP/setupManifold.js +71 -0
- package/src/BREP/threadGeometry.js +1120 -0
- package/src/BREP/triangleUtils.js +8 -0
- package/src/BREP/triangulate.js +608 -0
- package/src/FeatureRegistry.js +183 -0
- package/src/PartHistory.js +1132 -0
- package/src/UI/AccordionWidget.js +292 -0
- package/src/UI/CADmaterials.js +850 -0
- package/src/UI/EnvMonacoEditor.js +522 -0
- package/src/UI/FloatingWindow.js +396 -0
- package/src/UI/HistoryWidget.js +457 -0
- package/src/UI/MainToolbar.js +131 -0
- package/src/UI/ModelLibraryView.js +194 -0
- package/src/UI/OrthoCameraIdle.js +206 -0
- package/src/UI/PluginsWidget.js +280 -0
- package/src/UI/SceneListing.js +606 -0
- package/src/UI/SelectionFilter.js +629 -0
- package/src/UI/ViewCube.js +389 -0
- package/src/UI/assembly/AssemblyConstraintCollectionWidget.js +329 -0
- package/src/UI/assembly/AssemblyConstraintControlsWidget.js +282 -0
- package/src/UI/assembly/AssemblyConstraintsWidget.css +292 -0
- package/src/UI/assembly/AssemblyConstraintsWidget.js +1373 -0
- package/src/UI/assembly/constraintFaceUtils.js +115 -0
- package/src/UI/assembly/constraintHighlightUtils.js +70 -0
- package/src/UI/assembly/constraintLabelUtils.js +31 -0
- package/src/UI/assembly/constraintPointUtils.js +64 -0
- package/src/UI/assembly/constraintSelectionUtils.js +185 -0
- package/src/UI/assembly/constraintStatusUtils.js +142 -0
- package/src/UI/componentSelectorModal.js +240 -0
- package/src/UI/controls/CombinedTransformControls.js +386 -0
- package/src/UI/dialogs.js +351 -0
- package/src/UI/expressionsManager.js +100 -0
- package/src/UI/featureDialogWidgets/booleanField.js +25 -0
- package/src/UI/featureDialogWidgets/booleanOperationField.js +97 -0
- package/src/UI/featureDialogWidgets/buttonField.js +45 -0
- package/src/UI/featureDialogWidgets/componentSelectorField.js +102 -0
- package/src/UI/featureDialogWidgets/defaultField.js +23 -0
- package/src/UI/featureDialogWidgets/fileField.js +66 -0
- package/src/UI/featureDialogWidgets/index.js +34 -0
- package/src/UI/featureDialogWidgets/numberField.js +165 -0
- package/src/UI/featureDialogWidgets/optionsField.js +33 -0
- package/src/UI/featureDialogWidgets/referenceSelectionField.js +208 -0
- package/src/UI/featureDialogWidgets/stringField.js +24 -0
- package/src/UI/featureDialogWidgets/textareaField.js +28 -0
- package/src/UI/featureDialogWidgets/threadDesignationField.js +160 -0
- package/src/UI/featureDialogWidgets/transformField.js +252 -0
- package/src/UI/featureDialogWidgets/utils.js +43 -0
- package/src/UI/featureDialogWidgets/vec3Field.js +133 -0
- package/src/UI/featureDialogs.js +1414 -0
- package/src/UI/fileManagerWidget.js +615 -0
- package/src/UI/history/HistoryCollectionWidget.js +1294 -0
- package/src/UI/history/historyCollectionWidget.css.js +257 -0
- package/src/UI/history/historyDisplayInfo.js +133 -0
- package/src/UI/mobile.js +28 -0
- package/src/UI/objectDump.js +442 -0
- package/src/UI/pmi/AnnotationCollectionWidget.js +120 -0
- package/src/UI/pmi/AnnotationHistory.js +353 -0
- package/src/UI/pmi/AnnotationRegistry.js +90 -0
- package/src/UI/pmi/BaseAnnotation.js +269 -0
- package/src/UI/pmi/LabelOverlay.css +102 -0
- package/src/UI/pmi/LabelOverlay.js +191 -0
- package/src/UI/pmi/PMIMode.js +1550 -0
- package/src/UI/pmi/PMIViewsWidget.js +1098 -0
- package/src/UI/pmi/annUtils.js +729 -0
- package/src/UI/pmi/dimensions/AngleDimensionAnnotation.js +647 -0
- package/src/UI/pmi/dimensions/ExplodeBodyAnnotation.js +507 -0
- package/src/UI/pmi/dimensions/HoleCalloutAnnotation.js +462 -0
- package/src/UI/pmi/dimensions/LeaderAnnotation.js +403 -0
- package/src/UI/pmi/dimensions/LinearDimensionAnnotation.js +532 -0
- package/src/UI/pmi/dimensions/NoteAnnotation.js +110 -0
- package/src/UI/pmi/dimensions/RadialDimensionAnnotation.js +659 -0
- package/src/UI/pmi/pmiStyle.js +44 -0
- package/src/UI/sketcher/SketchMode3D.js +4095 -0
- package/src/UI/sketcher/dimensions.js +674 -0
- package/src/UI/sketcher/glyphs.js +236 -0
- package/src/UI/sketcher/highlights.js +60 -0
- package/src/UI/toolbarButtons/aboutButton.js +5 -0
- package/src/UI/toolbarButtons/exportButton.js +609 -0
- package/src/UI/toolbarButtons/flatPatternButton.js +307 -0
- package/src/UI/toolbarButtons/importButton.js +160 -0
- package/src/UI/toolbarButtons/inspectorToggleButton.js +12 -0
- package/src/UI/toolbarButtons/metadataButton.js +1063 -0
- package/src/UI/toolbarButtons/orientToFaceButton.js +114 -0
- package/src/UI/toolbarButtons/registerDefaultButtons.js +46 -0
- package/src/UI/toolbarButtons/saveButton.js +99 -0
- package/src/UI/toolbarButtons/scriptRunnerButton.js +302 -0
- package/src/UI/toolbarButtons/testsButton.js +26 -0
- package/src/UI/toolbarButtons/undoRedoButtons.js +25 -0
- package/src/UI/toolbarButtons/wireframeToggleButton.js +5 -0
- package/src/UI/toolbarButtons/zoomToFitButton.js +5 -0
- package/src/UI/triangleDebuggerWindow.js +945 -0
- package/src/UI/viewer.js +4228 -0
- package/src/assemblyConstraints/AssemblyConstraintHistory.js +1576 -0
- package/src/assemblyConstraints/AssemblyConstraintRegistry.js +120 -0
- package/src/assemblyConstraints/BaseAssemblyConstraint.js +66 -0
- package/src/assemblyConstraints/constraintExpressionUtils.js +35 -0
- package/src/assemblyConstraints/constraintUtils/parallelAlignment.js +676 -0
- package/src/assemblyConstraints/constraints/AngleConstraint.js +485 -0
- package/src/assemblyConstraints/constraints/CoincidentConstraint.js +194 -0
- package/src/assemblyConstraints/constraints/DistanceConstraint.js +616 -0
- package/src/assemblyConstraints/constraints/FixedConstraint.js +78 -0
- package/src/assemblyConstraints/constraints/ParallelConstraint.js +252 -0
- package/src/assemblyConstraints/constraints/TouchAlignConstraint.js +961 -0
- package/src/core/entities/HistoryCollectionBase.js +72 -0
- package/src/core/entities/ListEntityBase.js +109 -0
- package/src/core/entities/schemaProcesser.js +121 -0
- package/src/exporters/sheetMetalFlatPattern.js +659 -0
- package/src/exporters/sheetMetalUnfold.js +862 -0
- package/src/exporters/step.js +1135 -0
- package/src/exporters/threeMF.js +575 -0
- package/src/features/assemblyComponent/AssemblyComponentFeature.js +780 -0
- package/src/features/boolean/BooleanFeature.js +94 -0
- package/src/features/chamfer/ChamferFeature.js +116 -0
- package/src/features/datium/DatiumFeature.js +80 -0
- package/src/features/edgeFeatureUtils.js +41 -0
- package/src/features/extrude/ExtrudeFeature.js +143 -0
- package/src/features/fillet/FilletFeature.js +197 -0
- package/src/features/helix/HelixFeature.js +405 -0
- package/src/features/hole/HoleFeature.js +1050 -0
- package/src/features/hole/screwClearance.js +86 -0
- package/src/features/hole/threadDesignationCatalog.js +149 -0
- package/src/features/imageHeightSolid/ImageHeightmapSolidFeature.js +463 -0
- package/src/features/imageToFace/ImageToFaceFeature.js +727 -0
- package/src/features/imageToFace/imageEditor.js +1270 -0
- package/src/features/imageToFace/traceUtils.js +971 -0
- package/src/features/import3dModel/Import3dModelFeature.js +151 -0
- package/src/features/loft/LoftFeature.js +605 -0
- package/src/features/mirror/MirrorFeature.js +151 -0
- package/src/features/offsetFace/OffsetFaceFeature.js +370 -0
- package/src/features/offsetShell/OffsetShellFeature.js +89 -0
- package/src/features/overlapCleanup/OverlapCleanupFeature.js +85 -0
- package/src/features/pattern/PatternFeature.js +275 -0
- package/src/features/patternLinear/PatternLinearFeature.js +120 -0
- package/src/features/patternRadial/PatternRadialFeature.js +186 -0
- package/src/features/plane/PlaneFeature.js +154 -0
- package/src/features/primitiveCone/primitiveConeFeature.js +99 -0
- package/src/features/primitiveCube/primitiveCubeFeature.js +70 -0
- package/src/features/primitiveCylinder/primitiveCylinderFeature.js +91 -0
- package/src/features/primitivePyramid/primitivePyramidFeature.js +72 -0
- package/src/features/primitiveSphere/primitiveSphereFeature.js +62 -0
- package/src/features/primitiveTorus/primitiveTorusFeature.js +109 -0
- package/src/features/remesh/RemeshFeature.js +97 -0
- package/src/features/revolve/RevolveFeature.js +111 -0
- package/src/features/selectionUtils.js +118 -0
- package/src/features/sheetMetal/SheetMetalContourFlangeFeature.js +1656 -0
- package/src/features/sheetMetal/SheetMetalCutoutFeature.js +1056 -0
- package/src/features/sheetMetal/SheetMetalFlangeFeature.js +1568 -0
- package/src/features/sheetMetal/SheetMetalHemFeature.js +43 -0
- package/src/features/sheetMetal/SheetMetalObject.js +141 -0
- package/src/features/sheetMetal/SheetMetalTabFeature.js +176 -0
- package/src/features/sheetMetal/UNFOLD_NEUTRAL_REQUIREMENTS.md +153 -0
- package/src/features/sheetMetal/contour-flange-rebuild-spec.md +261 -0
- package/src/features/sheetMetal/profileUtils.js +25 -0
- package/src/features/sheetMetal/sheetMetalCleanup.js +9 -0
- package/src/features/sheetMetal/sheetMetalFaceTypes.js +146 -0
- package/src/features/sheetMetal/sheetMetalMetadata.js +165 -0
- package/src/features/sheetMetal/sheetMetalPipeline.js +169 -0
- package/src/features/sheetMetal/sheetMetalProfileUtils.js +216 -0
- package/src/features/sheetMetal/sheetMetalTabUtils.js +29 -0
- package/src/features/sheetMetal/sheetMetalTree.js +210 -0
- package/src/features/sketch/SketchFeature.js +955 -0
- package/src/features/sketch/sketchSolver2D/ConstraintEngine.js +800 -0
- package/src/features/sketch/sketchSolver2D/constraintDefinitions.js +704 -0
- package/src/features/sketch/sketchSolver2D/mathHelpersMod.js +307 -0
- package/src/features/spline/SplineEditorSession.js +988 -0
- package/src/features/spline/SplineFeature.js +1388 -0
- package/src/features/spline/splineUtils.js +218 -0
- package/src/features/sweep/SweepFeature.js +110 -0
- package/src/features/transform/TransformFeature.js +152 -0
- package/src/features/tube/TubeFeature.js +635 -0
- package/src/fs.proxy.js +625 -0
- package/src/idbStorage.js +254 -0
- package/src/index.js +12 -0
- package/src/main.js +15 -0
- package/src/metadataManager.js +64 -0
- package/src/path.proxy.js +277 -0
- package/src/plugins/ghLoader.worker.js +151 -0
- package/src/plugins/pluginManager.js +286 -0
- package/src/pmi/PMIViewsManager.js +134 -0
- package/src/services/componentLibrary.js +198 -0
- package/src/tests/ConsoleCapture.js +189 -0
- package/src/tests/S7-diagnostics-2025-12-23T18-37-23-570Z.json +630 -0
- package/src/tests/browserTests.js +597 -0
- package/src/tests/debugBoolean.js +225 -0
- package/src/tests/partFiles/badBoolean.json +957 -0
- package/src/tests/partFiles/extrudeTest.json +88 -0
- package/src/tests/partFiles/filletFail.json +58 -0
- package/src/tests/partFiles/import_TEst.part.part.json +646 -0
- package/src/tests/partFiles/sheetMetalHem.BREP.json +734 -0
- package/src/tests/test_boolean_subtract.js +27 -0
- package/src/tests/test_chamfer.js +17 -0
- package/src/tests/test_extrudeFace.js +24 -0
- package/src/tests/test_fillet.js +17 -0
- package/src/tests/test_fillet_nonClosed.js +45 -0
- package/src/tests/test_filletsMoreDifficult.js +46 -0
- package/src/tests/test_history_features_basic.js +149 -0
- package/src/tests/test_hole.js +282 -0
- package/src/tests/test_mirror.js +16 -0
- package/src/tests/test_offsetShellGrouping.js +85 -0
- package/src/tests/test_plane.js +4 -0
- package/src/tests/test_primitiveCone.js +11 -0
- package/src/tests/test_primitiveCube.js +7 -0
- package/src/tests/test_primitiveCylinder.js +8 -0
- package/src/tests/test_primitivePyramid.js +9 -0
- package/src/tests/test_primitiveSphere.js +17 -0
- package/src/tests/test_primitiveTorus.js +21 -0
- package/src/tests/test_pushFace.js +126 -0
- package/src/tests/test_sheetMetalContourFlange.js +125 -0
- package/src/tests/test_sheetMetal_features.js +80 -0
- package/src/tests/test_sketch_openLoop.js +45 -0
- package/src/tests/test_solidMetrics.js +58 -0
- package/src/tests/test_stlLoader.js +1889 -0
- package/src/tests/test_sweepFace.js +55 -0
- package/src/tests/test_tube.js +45 -0
- package/src/tests/test_tube_closedLoop.js +67 -0
- package/src/tests/tests.js +493 -0
- package/src/tools/assemblyConstraintDialogCapturePage.js +56 -0
- package/src/tools/dialogCapturePageFactory.js +227 -0
- package/src/tools/featureDialogCapturePage.js +47 -0
- package/src/tools/pmiAnnotationDialogCapturePage.js +60 -0
- package/src/utils/axisHelpers.js +99 -0
- package/src/utils/deepClone.js +69 -0
- package/src/utils/geometryTolerance.js +37 -0
- package/src/utils/normalizeTypeString.js +8 -0
- package/src/utils/xformMath.js +51 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Manifold } from "../SolidShared.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Solid authoring helpers: vertex/face ID management and convenience geometry.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Exact key for vertex uniquing (change to tolerance if needed). */
|
|
8
|
+
export function _key([x, y, z]) {
|
|
9
|
+
return `${x},${y},${z}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Return the index of `p`, adding it to the vertex buffer if new. */
|
|
13
|
+
export function _getPointIndex(p) {
|
|
14
|
+
// Validate that all coordinates are finite before adding to vertex buffer
|
|
15
|
+
if (!Array.isArray(p) || p.length < 3) {
|
|
16
|
+
console.error('Invalid point passed to _getPointIndex:', p);
|
|
17
|
+
throw new Error('Point must be an array with at least 3 elements');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const x = p[0], y = p[1], z = p[2];
|
|
21
|
+
if (!isFinite(x) || !isFinite(y) || !isFinite(z)) {
|
|
22
|
+
console.error('Non-finite coordinates in _getPointIndex:', {x, y, z});
|
|
23
|
+
throw new Error(`Invalid point coordinates: (${x}, ${y}, ${z}) - must be finite numbers`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const k = this._key(p);
|
|
27
|
+
const found = this._vertKeyToIndex.get(k);
|
|
28
|
+
if (found !== undefined) return found;
|
|
29
|
+
const idx = this._vertProperties.length / 3;
|
|
30
|
+
this._vertProperties.push(x, y, z);
|
|
31
|
+
this._vertKeyToIndex.set(k, idx);
|
|
32
|
+
return idx;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Map face name to unique Manifold ID, creating one if absent. */
|
|
36
|
+
export function _getOrCreateID(faceName) {
|
|
37
|
+
if (!this._faceNameToID.has(faceName)) {
|
|
38
|
+
const id = Manifold.reserveIDs(1); // globally unique, propagates through CSG
|
|
39
|
+
this._faceNameToID.set(faceName, id);
|
|
40
|
+
this._idToFaceName.set(id, faceName);
|
|
41
|
+
}
|
|
42
|
+
return this._faceNameToID.get(faceName);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Add a single triangle (CCW winding recommended).
|
|
47
|
+
* @param {string} faceName
|
|
48
|
+
* @param {[number,number,number]} v1
|
|
49
|
+
* @param {[number,number,number]} v2
|
|
50
|
+
* @param {[number,number,number]} v3
|
|
51
|
+
*/
|
|
52
|
+
export function addTriangle(faceName, v1, v2, v3) {
|
|
53
|
+
const id = this._getOrCreateID(faceName);
|
|
54
|
+
const i1 = this._getPointIndex(v1);
|
|
55
|
+
const i2 = this._getPointIndex(v2);
|
|
56
|
+
const i3 = this._getPointIndex(v3);
|
|
57
|
+
this._triVerts.push(i1, i2, i3);
|
|
58
|
+
this._triIDs.push(id);
|
|
59
|
+
this._dirty = true;
|
|
60
|
+
this._faceIndex = null;
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Add a helper/auxiliary edge polyline to this solid (e.g., a centerline).
|
|
66
|
+
* @param {string} name Label for the edge
|
|
67
|
+
* @param {Array<[number,number,number]>} points Polyline points
|
|
68
|
+
* @param {object} [options]
|
|
69
|
+
* @param {boolean} [options.closedLoop=false] Render the edge as a closed loop when visualized
|
|
70
|
+
* @param {boolean} [options.polylineWorld=false] Whether the points are already in world space
|
|
71
|
+
* @param {'OVERLAY'|'BASE'|string} [options.materialKey='OVERLAY'] Material tag for visualization
|
|
72
|
+
*/
|
|
73
|
+
export function addAuxEdge(name, points, options = {}) {
|
|
74
|
+
try {
|
|
75
|
+
const toArr = (p) => {
|
|
76
|
+
if (Array.isArray(p) && p.length === 3) return [p[0], p[1], p[2]];
|
|
77
|
+
if (p && typeof p === 'object') {
|
|
78
|
+
const x = +p.x, y = +p.y, z = +p.z;
|
|
79
|
+
if (Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(z)) return [x, y, z];
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
};
|
|
83
|
+
const pts = Array.isArray(points)
|
|
84
|
+
? points.map(toArr).filter(Boolean)
|
|
85
|
+
: [];
|
|
86
|
+
if (pts.length < 2) return this;
|
|
87
|
+
const label = name || 'EDGE';
|
|
88
|
+
const hasCenterlineOption = Object.prototype.hasOwnProperty.call(options || {}, 'centerline');
|
|
89
|
+
const inferredCenterline = typeof label === 'string' && /centerline/i.test(label);
|
|
90
|
+
const centerline = hasCenterlineOption ? !!options.centerline : inferredCenterline;
|
|
91
|
+
const entry = {
|
|
92
|
+
name: label,
|
|
93
|
+
points: pts,
|
|
94
|
+
closedLoop: !!options.closedLoop,
|
|
95
|
+
polylineWorld: !!options.polylineWorld,
|
|
96
|
+
materialKey: options.materialKey || 'OVERLAY',
|
|
97
|
+
centerline,
|
|
98
|
+
};
|
|
99
|
+
if (!Array.isArray(this._auxEdges)) this._auxEdges = [];
|
|
100
|
+
this._auxEdges.push(entry);
|
|
101
|
+
} catch { /* ignore */ }
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Convenience: add a two-point centerline. */
|
|
106
|
+
export function addCenterline(a, b, name = 'CENTERLINE', options = {}) {
|
|
107
|
+
const A = Array.isArray(a) ? a : [a?.x || 0, a?.y || 0, a?.z || 0];
|
|
108
|
+
const B = Array.isArray(b) ? b : [b?.x || 0, b?.y || 0, b?.z || 0];
|
|
109
|
+
const opts = { ...(options || {}) };
|
|
110
|
+
if (!Object.prototype.hasOwnProperty.call(opts, 'centerline')) opts.centerline = true;
|
|
111
|
+
return this.addAuxEdge(name, [A, B], opts);
|
|
112
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Manifold } from "../SolidShared.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Boolean operations and manifold reconstruction helpers.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function _combineIdMaps(other) {
|
|
8
|
+
const merged = new Map(this._idToFaceName);
|
|
9
|
+
for (const [id, name] of other._idToFaceName.entries()) {
|
|
10
|
+
merged.set(id, name);
|
|
11
|
+
}
|
|
12
|
+
return merged;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function _collapseFaceIdsByName(solid) {
|
|
16
|
+
if (!solid || !solid._faceNameToID || !solid._idToFaceName || !Array.isArray(solid._triIDs)) return;
|
|
17
|
+
const nameToId = solid._faceNameToID;
|
|
18
|
+
let changed = false;
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < solid._triIDs.length; i++) {
|
|
21
|
+
const id = solid._triIDs[i];
|
|
22
|
+
const name = solid._idToFaceName.get(id);
|
|
23
|
+
if (!name) continue;
|
|
24
|
+
const canonical = nameToId.get(name);
|
|
25
|
+
if (canonical !== undefined && canonical !== id) {
|
|
26
|
+
solid._triIDs[i] = canonical;
|
|
27
|
+
changed = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!changed) return;
|
|
32
|
+
|
|
33
|
+
solid._idToFaceName = new Map(
|
|
34
|
+
[...solid._faceNameToID.entries()].map(([name, id]) => [id, name]),
|
|
35
|
+
);
|
|
36
|
+
solid._faceIndex = null;
|
|
37
|
+
solid._dirty = true;
|
|
38
|
+
try { if (solid._manifold && typeof solid._manifold.delete === 'function') solid._manifold.delete(); } catch { }
|
|
39
|
+
solid._manifold = null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function baseSolidCtor(obj) {
|
|
43
|
+
const ctor = obj && obj.constructor;
|
|
44
|
+
return (ctor && ctor.BaseSolid) ? ctor.BaseSolid : ctor;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function union(other) {
|
|
48
|
+
const Solid = baseSolidCtor(this);
|
|
49
|
+
const outManifold = Manifold.union(this._manifoldize(), other._manifoldize());
|
|
50
|
+
const mergedMap = this._combineIdMaps(other);
|
|
51
|
+
const out = Solid._fromManifold(outManifold, mergedMap);
|
|
52
|
+
try { out.owningFeatureID = this?.owningFeatureID || other?.owningFeatureID || out?.owningFeatureID || null; } catch { }
|
|
53
|
+
try { out._auxEdges = [...(this._auxEdges || []), ...(other?._auxEdges || [])]; } catch { }
|
|
54
|
+
try { out._faceMetadata = this._combineFaceMetadata(other); } catch { }
|
|
55
|
+
try { out._edgeMetadata = this._combineEdgeMetadata(other); } catch { }
|
|
56
|
+
_collapseFaceIdsByName(out);
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function subtract(other) {
|
|
61
|
+
const Solid = baseSolidCtor(this);
|
|
62
|
+
const outManifold = this._manifoldize().subtract(other._manifoldize());
|
|
63
|
+
|
|
64
|
+
const mergedMap = this._combineIdMaps(other);
|
|
65
|
+
const out = Solid._fromManifold(outManifold, mergedMap);
|
|
66
|
+
try { out.owningFeatureID = this?.owningFeatureID || other?.owningFeatureID || out?.owningFeatureID || null; } catch { }
|
|
67
|
+
try { out._auxEdges = [...(this._auxEdges || []), ...(other?._auxEdges || [])]; } catch { }
|
|
68
|
+
try { out._faceMetadata = this._combineFaceMetadata(other); } catch { }
|
|
69
|
+
try { out._edgeMetadata = this._combineEdgeMetadata(other); } catch { }
|
|
70
|
+
_collapseFaceIdsByName(out);
|
|
71
|
+
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function intersect(other) {
|
|
76
|
+
const Solid = baseSolidCtor(this);
|
|
77
|
+
const outManifold = Manifold.intersection(this._manifoldize(), other._manifoldize());
|
|
78
|
+
const mergedMap = this._combineIdMaps(other);
|
|
79
|
+
const out = Solid._fromManifold(outManifold, mergedMap);
|
|
80
|
+
try { out.owningFeatureID = this?.owningFeatureID || other?.owningFeatureID || out?.owningFeatureID || null; } catch { }
|
|
81
|
+
try { out._auxEdges = [...(this._auxEdges || []), ...(other?._auxEdges || [])]; } catch { }
|
|
82
|
+
try { out._faceMetadata = this._combineFaceMetadata(other); } catch { }
|
|
83
|
+
try { out._edgeMetadata = this._combineEdgeMetadata(other); } catch { }
|
|
84
|
+
_collapseFaceIdsByName(out);
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Boolean difference A − B using Manifold's built-in API.
|
|
90
|
+
* Equivalent to `subtract`, provided for semantic clarity.
|
|
91
|
+
*/
|
|
92
|
+
export function difference(other) {
|
|
93
|
+
const Solid = baseSolidCtor(this);
|
|
94
|
+
const outManifold = Manifold.difference(this._manifoldize(), other._manifoldize());
|
|
95
|
+
const mergedMap = this._combineIdMaps(other);
|
|
96
|
+
const out = Solid._fromManifold(outManifold, mergedMap);
|
|
97
|
+
try { out.owningFeatureID = this?.owningFeatureID || other?.owningFeatureID || out?.owningFeatureID || null; } catch { }
|
|
98
|
+
try { out._auxEdges = [...(this._auxEdges || []), ...(other?._auxEdges || [])]; } catch { }
|
|
99
|
+
try { out._faceMetadata = this._combineFaceMetadata(other); } catch { }
|
|
100
|
+
try { out._edgeMetadata = this._combineEdgeMetadata(other); } catch { }
|
|
101
|
+
_collapseFaceIdsByName(out);
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function setTolerance(tolerance) {
|
|
106
|
+
const Solid = baseSolidCtor(this);
|
|
107
|
+
const m = this._manifoldize();
|
|
108
|
+
const outM = m.setTolerance(tolerance);
|
|
109
|
+
const mapCopy = new Map(this._idToFaceName);
|
|
110
|
+
const out = Solid._fromManifold(outM, mapCopy);
|
|
111
|
+
try { out._auxEdges = Array.isArray(this._auxEdges) ? this._auxEdges.slice() : []; } catch { }
|
|
112
|
+
try { out._faceMetadata = new Map(this._faceMetadata); } catch { }
|
|
113
|
+
try { out._edgeMetadata = new Map(this._edgeMetadata); } catch { }
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
export function simplify(tolerance = undefined, updateInPlace = false) {
|
|
117
|
+
const Solid = this.constructor;
|
|
118
|
+
const m = this._manifoldize();
|
|
119
|
+
|
|
120
|
+
// Run simplify on the manifold
|
|
121
|
+
const outM = (tolerance === undefined) ? m.simplify() : m.simplify(tolerance);
|
|
122
|
+
|
|
123
|
+
// Read back the simplified mesh and update this Solid in-place
|
|
124
|
+
let meshOut = null;
|
|
125
|
+
try {
|
|
126
|
+
meshOut = outM.getMesh();
|
|
127
|
+
|
|
128
|
+
// Replace geometry arrays
|
|
129
|
+
this._numProp = meshOut.numProp;
|
|
130
|
+
this._vertProperties = Array.from(meshOut.vertProperties);
|
|
131
|
+
this._triVerts = Array.from(meshOut.triVerts);
|
|
132
|
+
this._triIDs = Solid._expandTriIDsFromMesh(meshOut);
|
|
133
|
+
|
|
134
|
+
// Rebuild vertex key map
|
|
135
|
+
this._vertKeyToIndex = new Map();
|
|
136
|
+
for (let i = 0; i < this._vertProperties.length; i += 3) {
|
|
137
|
+
const x = this._vertProperties[i + 0];
|
|
138
|
+
const y = this._vertProperties[i + 1];
|
|
139
|
+
const z = this._vertProperties[i + 2];
|
|
140
|
+
this._vertKeyToIndex.set(`${x},${y},${z}`, (i / 3) | 0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Keep existing face name map; best-effort completion for any new IDs
|
|
144
|
+
const completeMap = new Map(this._idToFaceName);
|
|
145
|
+
try {
|
|
146
|
+
const ids = meshOut.faceID && meshOut.faceID.length ? meshOut.faceID : null;
|
|
147
|
+
const triCount = (meshOut.triVerts?.length || 0) / 3 | 0;
|
|
148
|
+
if (ids && ids.length === triCount) {
|
|
149
|
+
const seen = new Set();
|
|
150
|
+
for (let t = 0; t < triCount; t++) {
|
|
151
|
+
const id = ids[t] >>> 0;
|
|
152
|
+
if (seen.has(id)) continue;
|
|
153
|
+
seen.add(id);
|
|
154
|
+
if (!completeMap.has(id)) completeMap.set(id, `FACE_${id}`);
|
|
155
|
+
}
|
|
156
|
+
} else if (!ids) {
|
|
157
|
+
if (!completeMap.has(0)) completeMap.set(0, 'FACE_0');
|
|
158
|
+
}
|
|
159
|
+
} catch { /* ignore */ }
|
|
160
|
+
this._idToFaceName = completeMap;
|
|
161
|
+
this._faceNameToID = new Map(
|
|
162
|
+
[...this._idToFaceName.entries()].map(([id, name]) => [name, id]),
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
// Replace cached manifold and reset caches
|
|
166
|
+
try { if (this._manifold && this._manifold !== outM && typeof this._manifold.delete === 'function') this._manifold.delete(); } catch { }
|
|
167
|
+
this._manifold = outM;
|
|
168
|
+
this._dirty = false;
|
|
169
|
+
this._faceIndex = null;
|
|
170
|
+
} finally {
|
|
171
|
+
try { if (meshOut && typeof meshOut.delete === 'function') meshOut.delete(); } catch { }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const returnObject = updateInPlace ? this : Solid._fromManifold(outM, this._idToFaceName);
|
|
175
|
+
|
|
176
|
+
this._manifoldize();
|
|
177
|
+
// Return the mutated Solid (chainable)
|
|
178
|
+
return returnObject;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function _expandTriIDsFromMesh(mesh) {
|
|
182
|
+
if (mesh.faceID && mesh.faceID.length) {
|
|
183
|
+
return Array.from(mesh.faceID);
|
|
184
|
+
}
|
|
185
|
+
return new Array((mesh.triVerts.length / 3) | 0).fill(0);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function _fromManifold(manifoldObj, idToFaceName) {
|
|
189
|
+
const Solid = this;
|
|
190
|
+
const mesh = manifoldObj.getMesh();
|
|
191
|
+
const solid = new Solid();
|
|
192
|
+
|
|
193
|
+
solid._numProp = mesh.numProp;
|
|
194
|
+
solid._vertProperties = Array.from(mesh.vertProperties);
|
|
195
|
+
solid._triVerts = Array.from(mesh.triVerts);
|
|
196
|
+
solid._triIDs = Solid._expandTriIDsFromMesh(mesh);
|
|
197
|
+
|
|
198
|
+
for (let i = 0; i < mesh.vertProperties.length; i += 3) {
|
|
199
|
+
const x = mesh.vertProperties[i + 0];
|
|
200
|
+
const y = mesh.vertProperties[i + 1];
|
|
201
|
+
const z = mesh.vertProperties[i + 2];
|
|
202
|
+
solid._vertKeyToIndex.set(`${x},${y},${z}`, i / 3);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const completeMap = new Map(idToFaceName);
|
|
206
|
+
try {
|
|
207
|
+
const ids = mesh.faceID && mesh.faceID.length ? mesh.faceID : null;
|
|
208
|
+
const triCount = (mesh.triVerts?.length || 0) / 3 | 0;
|
|
209
|
+
if (ids && ids.length === triCount) {
|
|
210
|
+
const seen = new Set();
|
|
211
|
+
for (let t = 0; t < triCount; t++) {
|
|
212
|
+
const id = ids[t] >>> 0;
|
|
213
|
+
if (seen.has(id)) continue;
|
|
214
|
+
seen.add(id);
|
|
215
|
+
if (!completeMap.has(id)) completeMap.set(id, `FACE_${id}`);
|
|
216
|
+
}
|
|
217
|
+
} else if (!ids) {
|
|
218
|
+
if (!completeMap.has(0)) completeMap.set(0, 'FACE_0');
|
|
219
|
+
}
|
|
220
|
+
} catch (_) { /* best-effort completion */ }
|
|
221
|
+
|
|
222
|
+
solid._idToFaceName = new Map(completeMap);
|
|
223
|
+
solid._faceNameToID = new Map(
|
|
224
|
+
[...solid._idToFaceName.entries()].map(([id, name]) => [name, id]),
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
solid._manifold = manifoldObj;
|
|
228
|
+
solid._dirty = false;
|
|
229
|
+
try { return solid; } finally { try { if (mesh && typeof mesh.delete === 'function') mesh.delete(); } catch { } }
|
|
230
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Solid.chamfer implementation: wraps ChamferSolid builder and applies booleans.
|
|
2
|
+
import { resolveEdgesFromInputs } from './edgeResolution.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Apply chamfers to this Solid and return a new Solid with the result.
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} opts
|
|
8
|
+
* @param {number} opts.distance Required chamfer distance (> 0)
|
|
9
|
+
* @param {string[]} [opts.edgeNames] Optional edge names to chamfer
|
|
10
|
+
* @param {any[]} [opts.edges] Optional pre-resolved Edge objects (must belong to this Solid)
|
|
11
|
+
* @param {'INSET'|'OUTSET'|string} [opts.direction='INSET'] Boolean behavior (subtract vs union)
|
|
12
|
+
* @param {number} [opts.inflate=0.1] Grow/shrink chamfer tool (negated for OUTSET)
|
|
13
|
+
* @param {boolean} [opts.debug=false] Enable debug helpers on ChamferSolid
|
|
14
|
+
* @param {string} [opts.featureID='CHAMFER'] For naming of intermediates and result
|
|
15
|
+
* @param {number} [opts.sampleCount] Optional sampling override for chamfer strip
|
|
16
|
+
* @param {boolean} [opts.snapSeamToEdge] Snap seam to the edge
|
|
17
|
+
* @param {number} [opts.sideStripSubdiv] Side strip subdivisions
|
|
18
|
+
* @param {number} [opts.seamInsetScale] Inset scale for seam
|
|
19
|
+
* @param {boolean} [opts.flipSide] Flip side selection
|
|
20
|
+
* @param {number} [opts.debugStride] Sampling stride for debug output
|
|
21
|
+
* @returns {import('../BetterSolid.js').Solid}
|
|
22
|
+
*/
|
|
23
|
+
export async function chamfer(opts = {}) {
|
|
24
|
+
const { ChamferSolid } = await import("../chamfer.js");
|
|
25
|
+
const distance = Number(opts.distance);
|
|
26
|
+
if (!Number.isFinite(distance) || distance <= 0) {
|
|
27
|
+
throw new Error(`Solid.chamfer: distance must be > 0, got ${opts.distance}`);
|
|
28
|
+
}
|
|
29
|
+
const dir = String(opts.direction || 'INSET').toUpperCase();
|
|
30
|
+
const inflateRaw = Number.isFinite(opts.inflate) ? Number(opts.inflate) : 0.1;
|
|
31
|
+
const inflateForSolid = (dir === 'OUTSET') ? -inflateRaw : inflateRaw;
|
|
32
|
+
const debug = !!opts.debug;
|
|
33
|
+
const featureID = opts.featureID || 'CHAMFER';
|
|
34
|
+
console.log('[Solid.chamfer] Begin', {
|
|
35
|
+
featureID,
|
|
36
|
+
solid: this?.name,
|
|
37
|
+
distance,
|
|
38
|
+
direction: dir,
|
|
39
|
+
inflate: inflateRaw,
|
|
40
|
+
inflateApplied: inflateForSolid,
|
|
41
|
+
debug,
|
|
42
|
+
requestedEdgeNames: Array.isArray(opts.edgeNames) ? opts.edgeNames : [],
|
|
43
|
+
providedEdgeCount: Array.isArray(opts.edges) ? opts.edges.length : 0,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Resolve edges from names and/or provided objects
|
|
47
|
+
const unique = resolveEdgesFromInputs(this, { edgeNames: opts.edgeNames, edges: opts.edges });
|
|
48
|
+
if (unique.length === 0) {
|
|
49
|
+
console.warn('[Solid.chamfer] No edges resolved on target solid; returning clone.', { featureID, solid: this?.name });
|
|
50
|
+
const c = this.clone();
|
|
51
|
+
try { c.name = this.name; } catch { }
|
|
52
|
+
return c;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const chamferSolids = [];
|
|
56
|
+
let idx = 0;
|
|
57
|
+
for (const e of unique) {
|
|
58
|
+
const name = `${featureID}_CHAMFER_${idx++}`;
|
|
59
|
+
try {
|
|
60
|
+
const chamfer = new ChamferSolid({
|
|
61
|
+
edgeToChamfer: e,
|
|
62
|
+
distance,
|
|
63
|
+
direction: dir,
|
|
64
|
+
inflate: inflateForSolid,
|
|
65
|
+
debug,
|
|
66
|
+
sampleCount: opts.sampleCount,
|
|
67
|
+
snapSeamToEdge: opts.snapSeamToEdge,
|
|
68
|
+
sideStripSubdiv: opts.sideStripSubdiv,
|
|
69
|
+
seamInsetScale: opts.seamInsetScale,
|
|
70
|
+
flipSide: opts.flipSide,
|
|
71
|
+
debugStride: opts.debugStride,
|
|
72
|
+
});
|
|
73
|
+
try { chamfer.name = name; } catch { }
|
|
74
|
+
chamferSolids.push(chamfer);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.warn('[Solid.chamfer] Failed to build chamfer solid for edge', { edge: e?.name, error: err?.message || err });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (chamferSolids.length === 0) {
|
|
81
|
+
console.error('[Solid.chamfer] All chamfer solids failed; returning clone.', { featureID, edgeCount: unique.length });
|
|
82
|
+
const c = this.clone();
|
|
83
|
+
try { c.name = this.name; } catch { }
|
|
84
|
+
return c;
|
|
85
|
+
}
|
|
86
|
+
console.log('[Solid.chamfer] Built chamfer solids for edges', chamferSolids.length);
|
|
87
|
+
|
|
88
|
+
// Apply to base solid (union for OUTSET, subtract for INSET)
|
|
89
|
+
let result = this;
|
|
90
|
+
for (const chamferSolid of chamferSolids) {
|
|
91
|
+
const beforeTri = Array.isArray(result?._triVerts) ? (result._triVerts.length / 3) : 0;
|
|
92
|
+
result = (dir === 'OUTSET') ? result.union(chamferSolid) : result.subtract(chamferSolid);
|
|
93
|
+
const afterTri = Array.isArray(result?._triVerts) ? (result._triVerts.length / 3) : 0;
|
|
94
|
+
console.log('[Solid.chamfer] Applied chamfer boolean', {
|
|
95
|
+
featureID,
|
|
96
|
+
operation: (dir === 'OUTSET') ? 'union' : 'subtract',
|
|
97
|
+
beforeTriangles: beforeTri,
|
|
98
|
+
afterTriangles: afterTri,
|
|
99
|
+
});
|
|
100
|
+
try { result.name = this.name; } catch { }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Expose chamfer tool solids for debug/inspection (e.g., ChamferFeature)
|
|
104
|
+
try { result.__debugChamferSolids = chamferSolids; } catch { }
|
|
105
|
+
|
|
106
|
+
const finalTriCount = Array.isArray(result?._triVerts) ? (result._triVerts.length / 3) : 0;
|
|
107
|
+
const finalVertCount = Array.isArray(result?._vertProperties) ? (result._vertProperties.length / 3) : 0;
|
|
108
|
+
if (!result || finalTriCount === 0 || finalVertCount === 0) {
|
|
109
|
+
console.error('[Solid.chamfer] Chamfer result is empty or missing geometry.', {
|
|
110
|
+
featureID,
|
|
111
|
+
finalTriCount,
|
|
112
|
+
finalVertCount,
|
|
113
|
+
edgeCount: unique.length,
|
|
114
|
+
direction: dir,
|
|
115
|
+
inflate: inflateRaw,
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
console.log('[Solid.chamfer] Completed', { featureID, triangles: finalTriCount, vertices: finalVertCount });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function resolveEdgesFromInputs(solid, { edgeNames, edges } = {}) {
|
|
2
|
+
const edgeObjs = [];
|
|
3
|
+
const wantNames = Array.isArray(edgeNames) ? Array.from(new Set(edgeNames.map(String))) : [];
|
|
4
|
+
if (wantNames.length) {
|
|
5
|
+
for (const ch of solid?.children || []) {
|
|
6
|
+
if (ch && ch.type === 'EDGE' && wantNames.includes(ch.name)) {
|
|
7
|
+
if (ch.parentSolid === solid || ch.parent === solid) edgeObjs.push(ch);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(edges)) {
|
|
12
|
+
for (const e of edges) {
|
|
13
|
+
if (e && (e.parentSolid === solid || e.parent === solid)) edgeObjs.push(e);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const unique = [];
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
for (const e of edgeObjs) {
|
|
19
|
+
if (e && !seen.has(e)) {
|
|
20
|
+
seen.add(e);
|
|
21
|
+
unique.push(e);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return unique;
|
|
25
|
+
}
|