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,508 @@
|
|
|
1
|
+
import {
|
|
2
|
+
THREE,
|
|
3
|
+
CADmaterials,
|
|
4
|
+
LineGeometry,
|
|
5
|
+
debugMode,
|
|
6
|
+
Edge,
|
|
7
|
+
Vertex,
|
|
8
|
+
Face
|
|
9
|
+
} from "../SolidShared.js";
|
|
10
|
+
import { SHEET_METAL_FACE_TYPES, resolveSheetMetalFaceType } from "../../features/sheetMetal/sheetMetalFaceTypes.js";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Build a Three.js Group of per-face meshes for visualization.
|
|
18
|
+
* - Each face label becomes its own Mesh with a single material.
|
|
19
|
+
* - By default, generates a deterministic color per face name.
|
|
20
|
+
* - Accepts a THREE reference or uses global window.THREE if available.
|
|
21
|
+
*
|
|
22
|
+
* @param {any} THREERef Optional reference to the three.js module/object.
|
|
23
|
+
* @param {object} options Optional settings
|
|
24
|
+
* @param {(name:string)=>any} options.materialForFace Optional factory returning a THREE.Material for a face
|
|
25
|
+
* @param {boolean} [options.wireframe=false] Render materials as wireframe
|
|
26
|
+
* @param {string} [options.name='Solid'] Name for the group
|
|
27
|
+
* @param {boolean} [options.showEdges=true] Include boundary polylines between faces
|
|
28
|
+
* @param {boolean} [options.forceAuthoring=false] Force authoring-based grouping instead of manifold mesh
|
|
29
|
+
* @param {boolean} [options.authoringOnly=false] Skip manifold path entirely (always use authoring arrays)
|
|
30
|
+
* @returns {any} THREE.Group containing one child Mesh per face
|
|
31
|
+
*/
|
|
32
|
+
export function visualize(options = {}) {
|
|
33
|
+
const Solid = this.constructor;
|
|
34
|
+
// Clear existing children and dispose resources
|
|
35
|
+
for (let i = this.children.length - 1; i >= 0; i--) {
|
|
36
|
+
const child = this.children[i];
|
|
37
|
+
this.remove(child);
|
|
38
|
+
if (child.geometry && typeof child.geometry.dispose === 'function') child.geometry.dispose();
|
|
39
|
+
const mat = child.material;
|
|
40
|
+
if (mat) {
|
|
41
|
+
if (Array.isArray(mat)) mat.forEach(m => m && m.dispose && m.dispose());
|
|
42
|
+
else if (typeof mat.dispose === 'function') mat.dispose();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { showEdges = true, forceAuthoring = false, authoringOnly = false } = options;
|
|
47
|
+
let faces; let usedFallback = false;
|
|
48
|
+
if (!forceAuthoring && !authoringOnly) {
|
|
49
|
+
try {
|
|
50
|
+
faces = this.getFaces(false);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
console.warn('[Solid.visualize] getFaces failed, falling back to raw arrays:', err?.message || err);
|
|
53
|
+
usedFallback = true;
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
usedFallback = true;
|
|
57
|
+
}
|
|
58
|
+
if (usedFallback || !faces) {
|
|
59
|
+
// Fallback: group authored triangles by face name directly from arrays.
|
|
60
|
+
// This enables visualization even if manifoldization failed, which helps debugging.
|
|
61
|
+
const vp = this._vertProperties || [];
|
|
62
|
+
const tv = this._triVerts || [];
|
|
63
|
+
const ids = this._triIDs || [];
|
|
64
|
+
const nameOf = (id) => this._idToFaceName && this._idToFaceName.get ? this._idToFaceName.get(id) : String(id);
|
|
65
|
+
const nameToTris = new Map();
|
|
66
|
+
const triCount = (tv.length / 3) | 0;
|
|
67
|
+
for (let t = 0; t < triCount; t++) {
|
|
68
|
+
const id = ids[t];
|
|
69
|
+
const name = nameOf(id);
|
|
70
|
+
if (!name) continue;
|
|
71
|
+
let arr = nameToTris.get(name);
|
|
72
|
+
if (!arr) { arr = []; nameToTris.set(name, arr); }
|
|
73
|
+
const i0 = tv[t * 3 + 0], i1 = tv[t * 3 + 1], i2 = tv[t * 3 + 2];
|
|
74
|
+
const p0 = [vp[i0 * 3 + 0], vp[i0 * 3 + 1], vp[i0 * 3 + 2]];
|
|
75
|
+
const p1 = [vp[i1 * 3 + 0], vp[i1 * 3 + 1], vp[i1 * 3 + 2]];
|
|
76
|
+
const p2 = [vp[i2 * 3 + 0], vp[i2 * 3 + 1], vp[i2 * 3 + 2]];
|
|
77
|
+
arr.push({ faceName: name, indices: [i0, i1, i2], p1: p0, p2: p1, p3: p2 });
|
|
78
|
+
}
|
|
79
|
+
faces = [];
|
|
80
|
+
for (const [faceName, triangles] of nameToTris.entries()) faces.push({ faceName, triangles });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Build Face meshes and index by name
|
|
84
|
+
const faceMap = new Map();
|
|
85
|
+
for (const { faceName, triangles } of faces) {
|
|
86
|
+
if (!triangles.length) continue;
|
|
87
|
+
const positions = new Float32Array(triangles.length * 9);
|
|
88
|
+
let w = 0;
|
|
89
|
+
for (let t = 0; t < triangles.length; t++) {
|
|
90
|
+
const tri = triangles[t];
|
|
91
|
+
const p0 = tri.p1, p1 = tri.p2, p2 = tri.p3;
|
|
92
|
+
|
|
93
|
+
if (debugMode) {
|
|
94
|
+
// Validate triangle coordinates before adding to geometry
|
|
95
|
+
const coords = [p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0], p2[1], p2[2]];
|
|
96
|
+
const hasInvalidCoords = coords.some(coord => !isFinite(coord));
|
|
97
|
+
|
|
98
|
+
if (hasInvalidCoords) {
|
|
99
|
+
console.error(`Invalid triangle coordinates in face ${faceName}, triangle ${t}:`);
|
|
100
|
+
console.error('p0:', p0, 'p1:', p1, 'p2:', p2);
|
|
101
|
+
console.error('Triangle data:', tri);
|
|
102
|
+
// Skip this triangle by not incrementing w and not setting positions
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Degenerate triangle check (area ~ 0) and log its points
|
|
107
|
+
// Compute squared area via cross product of edges (robust to uniform scale)
|
|
108
|
+
try {
|
|
109
|
+
const ux = p1[0] - p0[0], uy = p1[1] - p0[1], uz = p1[2] - p0[2];
|
|
110
|
+
const vx = p2[0] - p0[0], vy = p2[1] - p0[1], vz = p2[2] - p0[2];
|
|
111
|
+
const nx = uy * vz - uz * vy;
|
|
112
|
+
const ny = uz * vx - ux * vz;
|
|
113
|
+
const nz = ux * vy - uy * vx;
|
|
114
|
+
const area2 = nx * nx + ny * ny + nz * nz;
|
|
115
|
+
// Use same threshold as viewer diagnostics
|
|
116
|
+
if (area2 <= 1e-30) {
|
|
117
|
+
console.warn(`[Solid.visualize] Degenerate triangle in face ${faceName} @ index ${t}`);
|
|
118
|
+
console.warn('points:', {p0, p1, p2});
|
|
119
|
+
}
|
|
120
|
+
} catch { /* best-effort logging only */ }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
positions[w++] = p0[0]; positions[w++] = p0[1]; positions[w++] = p0[2];
|
|
124
|
+
positions[w++] = p1[0]; positions[w++] = p1[1]; positions[w++] = p1[2];
|
|
125
|
+
positions[w++] = p2[0]; positions[w++] = p2[1]; positions[w++] = p2[2];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const geom = new THREE.BufferGeometry();
|
|
129
|
+
geom.setAttribute('position', new THREE.BufferAttribute(positions, 3));
|
|
130
|
+
geom.computeVertexNormals();
|
|
131
|
+
geom.computeBoundingBox();
|
|
132
|
+
geom.computeBoundingSphere();
|
|
133
|
+
|
|
134
|
+
const faceObj = new Face(geom);
|
|
135
|
+
faceObj.name = faceName;
|
|
136
|
+
faceObj.userData.faceName = faceName;
|
|
137
|
+
faceObj.userData.__defaultMaterial = faceObj.material;
|
|
138
|
+
faceObj.parentSolid = this;
|
|
139
|
+
// Tag with the owning feature for inspector/debug traceability.
|
|
140
|
+
try { faceObj.owningFeatureID = this?.owningFeatureID || null; } catch { }
|
|
141
|
+
faceMap.set(faceName, faceObj);
|
|
142
|
+
this.add(faceObj);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (showEdges) {
|
|
146
|
+
if (!usedFallback) {
|
|
147
|
+
let polylines = [];
|
|
148
|
+
try { polylines = this.getBoundaryEdgePolylines() || []; } catch { polylines = []; }
|
|
149
|
+
// Safety net: if manifold-based extraction yielded no edges (e.g., faceID missing),
|
|
150
|
+
// fall back to authoring-based boundary extraction so we still visualize edges.
|
|
151
|
+
if (!Array.isArray(polylines) || polylines.length === 0) {
|
|
152
|
+
try { usedFallback = true; } catch { }
|
|
153
|
+
}
|
|
154
|
+
for (const e of polylines) {
|
|
155
|
+
const positions = new Float32Array(e.positions.length * 3);
|
|
156
|
+
let w = 0;
|
|
157
|
+
for (let i = 0; i < e.positions.length; i++) {
|
|
158
|
+
const p = e.positions[i];
|
|
159
|
+
positions[w++] = p[0]; positions[w++] = p[1]; positions[w++] = p[2];
|
|
160
|
+
}
|
|
161
|
+
const g = new LineGeometry();
|
|
162
|
+
g.setPositions(Array.from(positions));
|
|
163
|
+
try { g.computeBoundingSphere(); } catch { }
|
|
164
|
+
|
|
165
|
+
const edgeObj = new Edge(g);
|
|
166
|
+
edgeObj.name = e.name;
|
|
167
|
+
edgeObj.closedLoop = !!e.closedLoop;
|
|
168
|
+
edgeObj.userData = {
|
|
169
|
+
faceA: e.faceA,
|
|
170
|
+
faceB: e.faceB,
|
|
171
|
+
polylineLocal: e.positions,
|
|
172
|
+
closedLoop: !!e.closedLoop,
|
|
173
|
+
};
|
|
174
|
+
edgeObj.userData.__defaultMaterial = edgeObj.material;
|
|
175
|
+
annotateEdgeFromMetadata(edgeObj, this);
|
|
176
|
+
// For convenience in feature code, mirror THREE's parent with an explicit handle
|
|
177
|
+
edgeObj.parentSolid = this;
|
|
178
|
+
const fa = faceMap.get(e.faceA);
|
|
179
|
+
const fb = faceMap.get(e.faceB);
|
|
180
|
+
if (fa) fa.edges.push(edgeObj);
|
|
181
|
+
if (fb) fb.edges.push(edgeObj);
|
|
182
|
+
if (fa) edgeObj.faces.push(fa);
|
|
183
|
+
if (fb) edgeObj.faces.push(fb);
|
|
184
|
+
this.add(edgeObj);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (usedFallback) {
|
|
188
|
+
// Fallback boundary extraction from raw authoring arrays.
|
|
189
|
+
try {
|
|
190
|
+
const vp = this._vertProperties || [];
|
|
191
|
+
const tv = this._triVerts || [];
|
|
192
|
+
const ids = this._triIDs || [];
|
|
193
|
+
const nv = (vp.length / 3) | 0;
|
|
194
|
+
const triCount = (tv.length / 3) | 0;
|
|
195
|
+
const NV = BigInt(Math.max(1, nv));
|
|
196
|
+
const ukey = (a, b) => { const A = BigInt(a), B = BigInt(b); return A < B ? A * NV + B : B * NV + A; };
|
|
197
|
+
const e2t = new Map(); // key -> [{id,a,b,tri}...]
|
|
198
|
+
for (let t = 0; t < triCount; t++) {
|
|
199
|
+
const id = ids[t];
|
|
200
|
+
const base = t * 3;
|
|
201
|
+
const i0 = tv[base + 0] >>> 0, i1 = tv[base + 1] >>> 0, i2 = tv[base + 2] >>> 0;
|
|
202
|
+
const edges = [[i0, i1], [i1, i2], [i2, i0]];
|
|
203
|
+
for (let k = 0; k < 3; k++) {
|
|
204
|
+
const a = edges[k][0], b = edges[k][1];
|
|
205
|
+
const key = ukey(a, b);
|
|
206
|
+
let arr = e2t.get(key);
|
|
207
|
+
if (!arr) { arr = []; e2t.set(key, arr); }
|
|
208
|
+
arr.push({ id, a, b, tri: t });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Create polyline objects between differing face IDs (authoring labels)
|
|
212
|
+
const nameOf = (id) => this._idToFaceName && this._idToFaceName.get ? this._idToFaceName.get(id) : String(id);
|
|
213
|
+
const pairToEdges = new Map(); // pairKey -> array of [u,v]
|
|
214
|
+
for (const [key, arr] of e2t.entries()) {
|
|
215
|
+
if (arr.length !== 2) continue;
|
|
216
|
+
const a = arr[0], b = arr[1];
|
|
217
|
+
if (a.id === b.id) continue;
|
|
218
|
+
const nameA = nameOf(a.id), nameB = nameOf(b.id);
|
|
219
|
+
const pair = nameA < nameB ? [nameA, nameB] : [nameB, nameA];
|
|
220
|
+
const pairKey = JSON.stringify(pair);
|
|
221
|
+
let list = pairToEdges.get(pairKey);
|
|
222
|
+
if (!list) { list = []; pairToEdges.set(pairKey, list); }
|
|
223
|
+
const u = Math.min(a.a, a.b), v = Math.max(a.a, a.b);
|
|
224
|
+
list.push([u, v]);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const addPolyline = (nameA, nameB, indices) => {
|
|
228
|
+
const visited = new Set();
|
|
229
|
+
const adj = new Map();
|
|
230
|
+
const ek = (u, v) => (u < v ? `${u},${v}` : `${v},${u}`);
|
|
231
|
+
for (const [u, v] of indices) {
|
|
232
|
+
if (!adj.has(u)) adj.set(u, new Set());
|
|
233
|
+
if (!adj.has(v)) adj.set(v, new Set());
|
|
234
|
+
adj.get(u).add(v); adj.get(v).add(u);
|
|
235
|
+
}
|
|
236
|
+
const verts = (idx) => [vp[idx * 3 + 0], vp[idx * 3 + 1], vp[idx * 3 + 2]];
|
|
237
|
+
for (const [u0] of adj.entries()) {
|
|
238
|
+
// find start (degree 1) or any if loop
|
|
239
|
+
if ([...adj.get(u0)].length !== 1) continue;
|
|
240
|
+
const poly = [];
|
|
241
|
+
let u = u0, prev = -1;
|
|
242
|
+
while (true) {
|
|
243
|
+
const nbrs = [...adj.get(u)];
|
|
244
|
+
let v = nbrs[0];
|
|
245
|
+
if (v === prev && nbrs.length > 1) v = nbrs[1];
|
|
246
|
+
if (v === undefined) break;
|
|
247
|
+
const key = ek(u, v);
|
|
248
|
+
if (visited.has(key)) break;
|
|
249
|
+
visited.add(key);
|
|
250
|
+
poly.push(verts(u));
|
|
251
|
+
prev = u; u = v;
|
|
252
|
+
if (!adj.has(u)) break;
|
|
253
|
+
}
|
|
254
|
+
poly.push(verts(u));
|
|
255
|
+
if (poly.length >= 2) {
|
|
256
|
+
// Validate polyline coordinates before creating geometry
|
|
257
|
+
const flatCoords = poly.flat();
|
|
258
|
+
const hasInvalidCoords = flatCoords.some(coord => !isFinite(coord));
|
|
259
|
+
|
|
260
|
+
if (hasInvalidCoords) {
|
|
261
|
+
console.error('Invalid coordinates detected in edge polyline:');
|
|
262
|
+
console.error('Poly coordinates:', poly);
|
|
263
|
+
console.error('Flat coordinates:', flatCoords);
|
|
264
|
+
console.error('Face names:', nameA, '|', nameB);
|
|
265
|
+
continue; // Skip this edge
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const g = new LineGeometry();
|
|
269
|
+
g.setPositions(flatCoords);
|
|
270
|
+
try { g.computeBoundingSphere(); } catch { }
|
|
271
|
+
const edgeObj = new Edge(g);
|
|
272
|
+
edgeObj.name = `${nameA}|${nameB}`;
|
|
273
|
+
edgeObj.closedLoop = false;
|
|
274
|
+
edgeObj.userData = {
|
|
275
|
+
faceA: nameA,
|
|
276
|
+
faceB: nameB,
|
|
277
|
+
polylineLocal: poly,
|
|
278
|
+
closedLoop: false,
|
|
279
|
+
};
|
|
280
|
+
edgeObj.userData.__defaultMaterial = edgeObj.material;
|
|
281
|
+
annotateEdgeFromMetadata(edgeObj, this);
|
|
282
|
+
edgeObj.parentSolid = this;
|
|
283
|
+
const fa = faceMap.get(nameA); const fb = faceMap.get(nameB);
|
|
284
|
+
if (fa) fa.edges.push(edgeObj); if (fb) fb.edges.push(edgeObj);
|
|
285
|
+
if (fa) edgeObj.faces.push(fa); if (fb) edgeObj.faces.push(fb);
|
|
286
|
+
try { edgeObj.computeLineDistances(); } catch { }
|
|
287
|
+
this.add(edgeObj);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
for (const [pairKey, edgeList] of pairToEdges.entries()) {
|
|
292
|
+
const [a, b] = JSON.parse(pairKey);
|
|
293
|
+
addPolyline(a, b, edgeList);
|
|
294
|
+
}
|
|
295
|
+
} catch (_) { /* ignore fallback edge errors */ }
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Add auxiliary edges stored on this solid (e.g., centerlines)
|
|
300
|
+
try {
|
|
301
|
+
if (Array.isArray(this._auxEdges) && this._auxEdges.length) {
|
|
302
|
+
for (const aux of this._auxEdges) {
|
|
303
|
+
const pts = Array.isArray(aux?.points) ? aux.points.filter(p => Array.isArray(p) && p.length === 3) : [];
|
|
304
|
+
if (pts.length < 2) continue;
|
|
305
|
+
const flat = [];
|
|
306
|
+
for (const p of pts) { flat.push(p[0], p[1], p[2]); }
|
|
307
|
+
|
|
308
|
+
// If the auxiliary edge is marked as a closed loop, ensure the
|
|
309
|
+
// rendered polyline has an explicit closing segment by duplicating
|
|
310
|
+
// the first point at the end if necessary. This affects rendering
|
|
311
|
+
// only; stored userData remains unchanged for downstream consumers.
|
|
312
|
+
if (aux?.closedLoop && pts.length >= 2) {
|
|
313
|
+
const f = pts[0];
|
|
314
|
+
const l = pts[pts.length - 1];
|
|
315
|
+
const dx = l[0] - f[0];
|
|
316
|
+
const dy = l[1] - f[1];
|
|
317
|
+
const dz = l[2] - f[2];
|
|
318
|
+
const needsClosure = (dx !== 0) || (dy !== 0) || (dz !== 0);
|
|
319
|
+
if (needsClosure) {
|
|
320
|
+
flat.push(f[0], f[1], f[2]);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Validate auxiliary edge coordinates
|
|
325
|
+
const hasInvalidCoords = flat.some(coord => !isFinite(coord));
|
|
326
|
+
if (hasInvalidCoords) {
|
|
327
|
+
console.error('Invalid coordinates in auxiliary edge:', aux?.name || 'CENTERLINE');
|
|
328
|
+
console.error('Points:', pts);
|
|
329
|
+
console.error('Flat coordinates:', flat);
|
|
330
|
+
continue; // Skip this auxiliary edge
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const g = new LineGeometry();
|
|
334
|
+
g.setPositions(flat);
|
|
335
|
+
try { g.computeBoundingSphere(); } catch { }
|
|
336
|
+
const edgeObj = new Edge(g);
|
|
337
|
+
edgeObj.name = aux?.name || 'CENTERLINE';
|
|
338
|
+
edgeObj.closedLoop = !!aux?.closedLoop;
|
|
339
|
+
edgeObj.userData = {
|
|
340
|
+
...(edgeObj.userData || {}),
|
|
341
|
+
polylineLocal: pts,
|
|
342
|
+
polylineWorld: !!aux?.polylineWorld,
|
|
343
|
+
centerline: !!aux?.centerline,
|
|
344
|
+
auxEdge: true,
|
|
345
|
+
};
|
|
346
|
+
edgeObj.parentSolid = this;
|
|
347
|
+
try {
|
|
348
|
+
const key = (aux?.materialKey || 'OVERLAY').toUpperCase();
|
|
349
|
+
const edgeMats = CADmaterials?.EDGE || {};
|
|
350
|
+
const mat = edgeMats[key] || (key === 'OVERLAY' ? edgeMats.OVERLAY : null) || edgeMats.BASE;
|
|
351
|
+
if (mat) edgeObj.material = mat;
|
|
352
|
+
if (edgeObj.material && (key !== 'BASE')) {
|
|
353
|
+
edgeObj.material.depthTest = false;
|
|
354
|
+
edgeObj.material.depthWrite = false;
|
|
355
|
+
}
|
|
356
|
+
try { edgeObj.computeLineDistances(); } catch { }
|
|
357
|
+
edgeObj.renderOrder = 10020;
|
|
358
|
+
} catch { }
|
|
359
|
+
if (!edgeObj.userData) edgeObj.userData = {};
|
|
360
|
+
edgeObj.userData.__defaultMaterial = edgeObj.material;
|
|
361
|
+
this.add(edgeObj);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
} catch { /* ignore aux edge errors */ }
|
|
365
|
+
|
|
366
|
+
// Helper function to generate deterministic vertex names based on meeting edges
|
|
367
|
+
const generateVertexName = (position, meetingEdges) => {
|
|
368
|
+
if (!meetingEdges || meetingEdges.length === 0) {
|
|
369
|
+
return `VERTEX(${position[0]},${position[1]},${position[2]})`;
|
|
370
|
+
}
|
|
371
|
+
// Sort edge names for consistency, then join them
|
|
372
|
+
const sortedEdgeNames = [...meetingEdges].sort();
|
|
373
|
+
return `VERTEX[${sortedEdgeNames.join('+')}]`;
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
// Generate unique vertex objects at the start and end points of all edges
|
|
377
|
+
try {
|
|
378
|
+
const endpoints = new Map();
|
|
379
|
+
const vertexToEdges = new Map(); // Track which edges meet at each vertex
|
|
380
|
+
const usedVertexNames = new Set();
|
|
381
|
+
|
|
382
|
+
// First pass: collect all endpoint positions and track which edges meet at each vertex
|
|
383
|
+
for (const ch of this.children) {
|
|
384
|
+
if (!ch || ch.type !== 'EDGE') continue;
|
|
385
|
+
const poly = ch.userData && Array.isArray(ch.userData.polylineLocal) ? ch.userData.polylineLocal : null;
|
|
386
|
+
if (!poly || poly.length === 0) continue;
|
|
387
|
+
|
|
388
|
+
const edgeName = ch.name || 'UNNAMED_EDGE';
|
|
389
|
+
const first = poly[0];
|
|
390
|
+
const last = poly[poly.length - 1];
|
|
391
|
+
|
|
392
|
+
const addEP = (p) => {
|
|
393
|
+
if (!p || p.length !== 3) return;
|
|
394
|
+
const k = `${p[0]},${p[1]},${p[2]}`;
|
|
395
|
+
if (!endpoints.has(k)) endpoints.set(k, p);
|
|
396
|
+
|
|
397
|
+
// Track which edges meet at this vertex position
|
|
398
|
+
if (!vertexToEdges.has(k)) {
|
|
399
|
+
vertexToEdges.set(k, new Set());
|
|
400
|
+
}
|
|
401
|
+
vertexToEdges.get(k).add(edgeName);
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
addEP(first);
|
|
405
|
+
addEP(last);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Second pass: create vertices with deterministic names based on meeting edges
|
|
409
|
+
if (endpoints.size) {
|
|
410
|
+
for (const [positionKey, position] of endpoints.entries()) {
|
|
411
|
+
try {
|
|
412
|
+
const meetingEdges = vertexToEdges.get(positionKey);
|
|
413
|
+
let vertexName = generateVertexName(position, meetingEdges ? Array.from(meetingEdges) : []);
|
|
414
|
+
if (usedVertexNames.has(vertexName)) {
|
|
415
|
+
let suffix = 1;
|
|
416
|
+
while (usedVertexNames.has(`${vertexName}[${suffix}]`)) {
|
|
417
|
+
suffix++;
|
|
418
|
+
}
|
|
419
|
+
vertexName = `${vertexName}[${suffix}]`;
|
|
420
|
+
}
|
|
421
|
+
usedVertexNames.add(vertexName);
|
|
422
|
+
this.add(new Vertex(position, { name: vertexName }));
|
|
423
|
+
} catch { }
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
} catch { /* best-effort vertices */ }
|
|
427
|
+
|
|
428
|
+
return this;
|
|
429
|
+
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function annotateEdgeFromMetadata(edgeObj, solid) {
|
|
433
|
+
if (!edgeObj || !solid) return;
|
|
434
|
+
const edgeName = edgeObj.name || null;
|
|
435
|
+
if (!edgeName) return;
|
|
436
|
+
let meta = null;
|
|
437
|
+
try {
|
|
438
|
+
meta = typeof solid.getEdgeMetadata === "function" ? solid.getEdgeMetadata(edgeName) : null;
|
|
439
|
+
} catch { meta = null; }
|
|
440
|
+
if (meta && typeof meta === "object") {
|
|
441
|
+
edgeObj.userData = { ...(edgeObj.userData || {}), ...meta };
|
|
442
|
+
}
|
|
443
|
+
const seType = edgeObj.userData?.sheetMetalEdgeType;
|
|
444
|
+
if (seType && seType !== "AMBIGUOUS") return;
|
|
445
|
+
try {
|
|
446
|
+
// If edge metadata not populated, see if adjacent faces (or face metadata by name) carry a sheet-metal type
|
|
447
|
+
const faces = Array.isArray(edgeObj.faces) ? edgeObj.faces : [];
|
|
448
|
+
const faceTypes = new Set();
|
|
449
|
+
let hasSheetMeta = false;
|
|
450
|
+
let hasABCandidate = false;
|
|
451
|
+
for (const f of faces) {
|
|
452
|
+
const t = resolveSheetMetalFaceType(f);
|
|
453
|
+
if (t) hasSheetMeta = true;
|
|
454
|
+
if (t === SHEET_METAL_FACE_TYPES.A || t === SHEET_METAL_FACE_TYPES.B) {
|
|
455
|
+
faceTypes.add(t);
|
|
456
|
+
hasABCandidate = true;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
// Try userData face names if no attached face objects
|
|
460
|
+
if (!faceTypes.size && edgeObj.userData) {
|
|
461
|
+
const names = [];
|
|
462
|
+
if (edgeObj.userData.faceA) names.push(edgeObj.userData.faceA);
|
|
463
|
+
if (edgeObj.userData.faceB) names.push(edgeObj.userData.faceB);
|
|
464
|
+
for (const n of names) {
|
|
465
|
+
const m = typeof solid.getFaceMetadata === "function" ? solid.getFaceMetadata(n) : null;
|
|
466
|
+
const t = m?.sheetMetalFaceType;
|
|
467
|
+
if (t) hasSheetMeta = true;
|
|
468
|
+
if (t === SHEET_METAL_FACE_TYPES.A || t === SHEET_METAL_FACE_TYPES.B) {
|
|
469
|
+
faceTypes.add(t);
|
|
470
|
+
hasABCandidate = true;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (faceTypes.size >= 1) {
|
|
475
|
+
const t = [...faceTypes][0];
|
|
476
|
+
edgeObj.userData = { ...(edgeObj.userData || {}), sheetMetalEdgeType: t };
|
|
477
|
+
if (solid && typeof solid.setEdgeMetadata === "function") {
|
|
478
|
+
solid.setEdgeMetadata(edgeName, { ...(solid.getEdgeMetadata(edgeName) || {}), sheetMetalEdgeType: t });
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
// Fallback: derive from edge name segments via face metadata
|
|
482
|
+
const parts = typeof edgeName === "string" ? edgeName.split("|") : [];
|
|
483
|
+
let derivedType = null;
|
|
484
|
+
for (const p of parts) {
|
|
485
|
+
const meta = solid && typeof solid.getFaceMetadata === "function" ? solid.getFaceMetadata(p) : null;
|
|
486
|
+
const t = meta?.sheetMetalFaceType;
|
|
487
|
+
if (t) hasSheetMeta = true;
|
|
488
|
+
if (t === SHEET_METAL_FACE_TYPES.A || t === SHEET_METAL_FACE_TYPES.B) {
|
|
489
|
+
hasABCandidate = true;
|
|
490
|
+
derivedType = t;
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (derivedType) {
|
|
495
|
+
edgeObj.userData = { ...(edgeObj.userData || {}), sheetMetalEdgeType: derivedType };
|
|
496
|
+
if (solid && typeof solid.setEdgeMetadata === "function") {
|
|
497
|
+
solid.setEdgeMetadata(edgeName, { ...(solid.getEdgeMetadata(edgeName) || {}), sheetMetalEdgeType: derivedType });
|
|
498
|
+
}
|
|
499
|
+
} else if (hasSheetMeta && hasABCandidate) {
|
|
500
|
+
console.warn("[visualize] Edge has mixed or missing sheet metal face types", {
|
|
501
|
+
edge: edgeName,
|
|
502
|
+
faceTypes: Array.from(faceTypes),
|
|
503
|
+
faces: faces.map((f) => f?.name || f?.userData?.faceName || "UNKNOWN"),
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
} catch { /* ignore */ }
|
|
508
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Manifold, ManifoldMesh, CrossSection } from "./setupManifold.js";
|
|
2
|
+
|
|
3
|
+
import * as THREE from "three";
|
|
4
|
+
import { CADmaterials } from "../UI/CADmaterials.js";
|
|
5
|
+
import { Line2, LineGeometry } from "three/examples/jsm/Addons.js";
|
|
6
|
+
|
|
7
|
+
import { Edge } from "./Edge.js";
|
|
8
|
+
import { Vertex } from "./Vertex.js";
|
|
9
|
+
import { Face } from "./Face.js";
|
|
10
|
+
|
|
11
|
+
// Use named exports from setupManifold.js
|
|
12
|
+
|
|
13
|
+
const debugMode = false;
|
|
14
|
+
|
|
15
|
+
export { Edge, Vertex, Face };
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
Manifold,
|
|
19
|
+
ManifoldMesh,
|
|
20
|
+
CrossSection,
|
|
21
|
+
THREE,
|
|
22
|
+
CADmaterials,
|
|
23
|
+
Line2,
|
|
24
|
+
LineGeometry,
|
|
25
|
+
debugMode,
|
|
26
|
+
};
|