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,27 @@
|
|
|
1
|
+
|
|
2
|
+
export async function test_boolean_subtract(partHistory) {
|
|
3
|
+
const cone = await partHistory.newFeature("P.CO");
|
|
4
|
+
cone.inputParams.radiusTop = 3;
|
|
5
|
+
cone.inputParams.radiusBottom = .5;
|
|
6
|
+
cone.inputParams.height = 5.2;
|
|
7
|
+
cone.inputParams.resolution = 20;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
11
|
+
cube.inputParams.sizeX = 2;
|
|
12
|
+
cube.inputParams.sizeY = 2;
|
|
13
|
+
cube.inputParams.sizeZ = 20;
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const booleanFeature2 = await partHistory.newFeature("B");
|
|
17
|
+
booleanFeature2.inputParams.targetSolid = cube.inputParams.featureID;
|
|
18
|
+
booleanFeature2.inputParams.boolean = {
|
|
19
|
+
targets: [cone.inputParams.featureID],
|
|
20
|
+
operation: "SUBTRACT",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
return partHistory;
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export async function test_Chamfer(partHistory) {
|
|
2
|
+
// Base solid: cube to test planar chamfer along a face’s boundary
|
|
3
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
4
|
+
cube.inputParams.sizeX = 20;
|
|
5
|
+
cube.inputParams.sizeY = 20;
|
|
6
|
+
cube.inputParams.sizeZ = 20;
|
|
7
|
+
|
|
8
|
+
// Chamfer all edges of the +Z face (PZ)
|
|
9
|
+
const chamfer = await partHistory.newFeature("CHAMFER");
|
|
10
|
+
chamfer.inputParams.edges = [`${cube.inputParams.featureID}_PZ`]; // select face to include its edges
|
|
11
|
+
chamfer.inputParams.distance = 3.0;
|
|
12
|
+
chamfer.inputParams.inflate = 0.0005; // nudge to prevent tiny remainders
|
|
13
|
+
chamfer.inputParams.direction = "INSET"; // subtract from the base body
|
|
14
|
+
|
|
15
|
+
return partHistory;
|
|
16
|
+
}
|
|
17
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export async function test_ExtrudeFace(partHistory) {
|
|
2
|
+
const cone = await partHistory.newFeature("P.CO");
|
|
3
|
+
cone.inputParams.radiusTop = 3;
|
|
4
|
+
cone.inputParams.radiusBottom = .5;
|
|
5
|
+
cone.inputParams.height = 5.2;
|
|
6
|
+
cone.inputParams.resolution = 20;
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
const extrude = await partHistory.newFeature("E");
|
|
10
|
+
extrude.inputParams.profile = `${cone.inputParams.featureID}_T`;
|
|
11
|
+
// Use back distance instead of negative distance
|
|
12
|
+
extrude.inputParams.distance = 0;
|
|
13
|
+
extrude.inputParams.distanceBack = 5;
|
|
14
|
+
|
|
15
|
+
// Use internal boolean on the extrude feature to union with the cone
|
|
16
|
+
extrude.inputParams.boolean = {
|
|
17
|
+
targets: [cone.inputParams.featureID],
|
|
18
|
+
operation: "UNION",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// No separate boolean feature; handled internally by the extrude
|
|
22
|
+
|
|
23
|
+
return partHistory;
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export async function test_Fillet(partHistory) {
|
|
2
|
+
// Base solid: cylinder to provide a clean closed-loop edge at the top cap
|
|
3
|
+
const cyl = await partHistory.newFeature("P.CY");
|
|
4
|
+
cyl.inputParams.radius = 5;
|
|
5
|
+
cyl.inputParams.height = 10;
|
|
6
|
+
cyl.inputParams.resolution = 48;
|
|
7
|
+
|
|
8
|
+
// Apply a fillet along all edges of the top face (closed ring between _T and _S)
|
|
9
|
+
const fillet = await partHistory.newFeature("F");
|
|
10
|
+
fillet.inputParams.edges = [`${cyl.inputParams.featureID}_T`]; // select face to grab its edges
|
|
11
|
+
fillet.inputParams.radius = 1.0;
|
|
12
|
+
fillet.inputParams.inflate = 0.1; // tiny inflation to avoid sliver leftovers
|
|
13
|
+
fillet.inputParams.direction = "INSET"; // subtract from the base body
|
|
14
|
+
|
|
15
|
+
return partHistory;
|
|
16
|
+
}
|
|
17
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export async function test_Fillet_NonClosed(partHistory) {
|
|
2
|
+
// Create base solid: a cube
|
|
3
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
4
|
+
cube.inputParams.width = 10;
|
|
5
|
+
cube.inputParams.height = 10;
|
|
6
|
+
cube.inputParams.depth = 10;
|
|
7
|
+
|
|
8
|
+
// Fillet a single cube edge (non-closed path segment).
|
|
9
|
+
const fillet = await partHistory.newFeature("F");
|
|
10
|
+
fillet.inputParams.edges = [
|
|
11
|
+
`${cube.inputParams.featureID}_NX|${cube.inputParams.featureID}_NY[0]`,
|
|
12
|
+
];
|
|
13
|
+
fillet.inputParams.radius = 0.5;
|
|
14
|
+
fillet.inputParams.inflate = 0.1;
|
|
15
|
+
fillet.inputParams.direction = "INSET";
|
|
16
|
+
|
|
17
|
+
return partHistory;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function afterRun_Fillet_NonClosed(partHistory) {
|
|
21
|
+
// Verify that the fillet feature was created successfully
|
|
22
|
+
const filletFeature = partHistory.features.find((f) => f?.type === "F");
|
|
23
|
+
if (!filletFeature) {
|
|
24
|
+
throw new Error("Fillet feature missing from history");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Verify that the fillet solid exists in the scene
|
|
28
|
+
const filletGroup = (partHistory.scene?.children || []).find(
|
|
29
|
+
(obj) => obj?.owningFeatureID === filletFeature.inputParams.featureID
|
|
30
|
+
);
|
|
31
|
+
if (!filletGroup) throw new Error("Fillet group not found in scene");
|
|
32
|
+
|
|
33
|
+
// Check that the fillet has produced geometry
|
|
34
|
+
let solidCount = 0;
|
|
35
|
+
filletGroup.traverse((obj) => {
|
|
36
|
+
if (obj?.type === "SOLID") solidCount++;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (solidCount === 0) {
|
|
40
|
+
throw new Error("Fillet feature should produce at least one solid");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log(`✓ Non-closed fillet test passed: ${solidCount} solid(s) created`);
|
|
44
|
+
console.log(`✓ Tube centerline extended at both ends for non-closed loop`);
|
|
45
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export async function test_filletsMoreDifficult(partHistory) {
|
|
2
|
+
// Recreate the scenario from the provided saved state
|
|
3
|
+
|
|
4
|
+
// 1) Cone
|
|
5
|
+
const cone = await partHistory.newFeature("P.CO");
|
|
6
|
+
cone.inputParams.radiusTop = 3;
|
|
7
|
+
cone.inputParams.radiusBottom = 0.5;
|
|
8
|
+
cone.inputParams.height = 5.2;
|
|
9
|
+
cone.inputParams.resolution = "128";
|
|
10
|
+
// No boolean on cone (defaults to NONE)
|
|
11
|
+
|
|
12
|
+
// 2) Cube unioned with cone
|
|
13
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
14
|
+
cube.inputParams.sizeX = 5;
|
|
15
|
+
cube.inputParams.sizeY = 2;
|
|
16
|
+
cube.inputParams.sizeZ = 10;
|
|
17
|
+
cube.inputParams.boolean.targets = [cone.inputParams.featureID];
|
|
18
|
+
cube.inputParams.boolean.operation = 'UNION';
|
|
19
|
+
|
|
20
|
+
// 3) Fillet across intersection edge between cone side and cube +Y face
|
|
21
|
+
const fillet1 = await partHistory.newFeature("F");
|
|
22
|
+
fillet1.inputParams.edges = [
|
|
23
|
+
`${cone.inputParams.featureID}_S|${cube.inputParams.featureID}_PY[0]`,
|
|
24
|
+
];
|
|
25
|
+
fillet1.inputParams.radius = 1;
|
|
26
|
+
fillet1.inputParams.inflate = 0.1;
|
|
27
|
+
fillet1.inputParams.direction = "OUTSET";
|
|
28
|
+
fillet1.inputParams.debug = false;
|
|
29
|
+
|
|
30
|
+
// 4) Fillet around top ring of the cone
|
|
31
|
+
const fillet2 = await partHistory.newFeature("F");
|
|
32
|
+
fillet2.inputParams.edges = [
|
|
33
|
+
`${cone.inputParams.featureID}_S|${cone.inputParams.featureID}_T[0]`,
|
|
34
|
+
];
|
|
35
|
+
fillet2.inputParams.radius = 1;
|
|
36
|
+
fillet2.inputParams.inflate = 0.1;
|
|
37
|
+
fillet2.inputParams.direction = "INSET";
|
|
38
|
+
fillet2.inputParams.debug = false;
|
|
39
|
+
|
|
40
|
+
return partHistory;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Alias with the requested test name spelling for the runner/export folder
|
|
44
|
+
export async function test_fillets_more_dificult(partHistory) {
|
|
45
|
+
return test_filletsMoreDifficult(partHistory);
|
|
46
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
const makeRectSketch = (x0, y0, x1, y1, geomBase = 100) => ({
|
|
2
|
+
points: [
|
|
3
|
+
{ id: 0, x: x0, y: y0, fixed: true },
|
|
4
|
+
{ id: 1, x: x1, y: y0, fixed: false },
|
|
5
|
+
{ id: 2, x: x1, y: y1, fixed: false },
|
|
6
|
+
{ id: 3, x: x0, y: y1, fixed: false },
|
|
7
|
+
],
|
|
8
|
+
geometries: [
|
|
9
|
+
{ id: geomBase + 0, type: "line", points: [0, 1], construction: false },
|
|
10
|
+
{ id: geomBase + 1, type: "line", points: [1, 2], construction: false },
|
|
11
|
+
{ id: geomBase + 2, type: "line", points: [2, 3], construction: false },
|
|
12
|
+
{ id: geomBase + 3, type: "line", points: [3, 0], construction: false },
|
|
13
|
+
],
|
|
14
|
+
constraints: [{ id: 0, type: "⏚", points: [0] }],
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const makeLineSketch = (ax, ay, bx, by, geomId = 200) => ({
|
|
18
|
+
points: [
|
|
19
|
+
{ id: 0, x: ax, y: ay, fixed: true },
|
|
20
|
+
{ id: 1, x: bx, y: by, fixed: false },
|
|
21
|
+
],
|
|
22
|
+
geometries: [{ id: geomId, type: "line", points: [0, 1], construction: false }],
|
|
23
|
+
constraints: [{ id: 0, type: "⏚", points: [0] }],
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export async function test_history_features_basic(partHistory) {
|
|
27
|
+
const datum = await partHistory.newFeature("D");
|
|
28
|
+
datum.inputParams.transform = {
|
|
29
|
+
position: [1, 2, 3],
|
|
30
|
+
rotationEuler: [0, 30, 0],
|
|
31
|
+
scale: [1, 1, 1],
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const spline = await partHistory.newFeature("SP");
|
|
35
|
+
spline.persistentData.spline = {
|
|
36
|
+
points: [
|
|
37
|
+
{ id: "p0", position: [0, 0, 0], forwardDistance: 1, backwardDistance: 1, flipDirection: false },
|
|
38
|
+
{ id: "p1", position: [5, 2, 0], forwardDistance: 1, backwardDistance: 1, flipDirection: false },
|
|
39
|
+
{ id: "p2", position: [10, 0, 0], forwardDistance: 1, backwardDistance: 1, flipDirection: false },
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const helix = await partHistory.newFeature("HX");
|
|
44
|
+
helix.inputParams.radius = 2;
|
|
45
|
+
helix.inputParams.endRadius = 1.5;
|
|
46
|
+
helix.inputParams.height = 8;
|
|
47
|
+
helix.inputParams.turns = 2;
|
|
48
|
+
helix.inputParams.resolution = 32;
|
|
49
|
+
|
|
50
|
+
const planeA = await partHistory.newFeature("P");
|
|
51
|
+
planeA.inputParams.orientation = "XY";
|
|
52
|
+
const planeB = await partHistory.newFeature("P");
|
|
53
|
+
planeB.inputParams.orientation = "XY";
|
|
54
|
+
planeB.inputParams.offset_distance = 5;
|
|
55
|
+
|
|
56
|
+
const loftSketchA = await partHistory.newFeature("S");
|
|
57
|
+
loftSketchA.inputParams.sketchPlane = planeA.inputParams.featureID;
|
|
58
|
+
loftSketchA.persistentData.sketch = makeRectSketch(0, 0, 10, 10, 100);
|
|
59
|
+
|
|
60
|
+
const loftSketchB = await partHistory.newFeature("S");
|
|
61
|
+
loftSketchB.inputParams.sketchPlane = planeB.inputParams.featureID;
|
|
62
|
+
loftSketchB.persistentData.sketch = makeRectSketch(2, 2, 8, 8, 200);
|
|
63
|
+
|
|
64
|
+
const loft = await partHistory.newFeature("LOFT");
|
|
65
|
+
loft.inputParams.profiles = [
|
|
66
|
+
loftSketchA.inputParams.featureID,
|
|
67
|
+
loftSketchB.inputParams.featureID,
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const axisSketch = await partHistory.newFeature("S");
|
|
71
|
+
axisSketch.inputParams.sketchPlane = planeA.inputParams.featureID;
|
|
72
|
+
axisSketch.persistentData.sketch = makeLineSketch(0, -5, 0, 5, 300);
|
|
73
|
+
const axisEdgeName = `${axisSketch.inputParams.featureID}:G300`;
|
|
74
|
+
|
|
75
|
+
const revolveSketch = await partHistory.newFeature("S");
|
|
76
|
+
revolveSketch.inputParams.sketchPlane = planeA.inputParams.featureID;
|
|
77
|
+
revolveSketch.persistentData.sketch = makeRectSketch(4, -2, 7, 2, 400);
|
|
78
|
+
|
|
79
|
+
const revolve = await partHistory.newFeature("R");
|
|
80
|
+
revolve.inputParams.profile = revolveSketch.inputParams.featureID;
|
|
81
|
+
revolve.inputParams.axis = axisEdgeName;
|
|
82
|
+
revolve.inputParams.angle = 180;
|
|
83
|
+
revolve.inputParams.resolution = 32;
|
|
84
|
+
|
|
85
|
+
const remeshBase = await partHistory.newFeature("P.CU");
|
|
86
|
+
const remesh = await partHistory.newFeature("RM");
|
|
87
|
+
remesh.inputParams.targetSolid = remeshBase.inputParams.featureID;
|
|
88
|
+
remesh.inputParams.mode = "Simplify";
|
|
89
|
+
remesh.inputParams.tolerance = 0.05;
|
|
90
|
+
|
|
91
|
+
const xformBase = await partHistory.newFeature("P.CU");
|
|
92
|
+
const xform = await partHistory.newFeature("XFORM");
|
|
93
|
+
xform.inputParams.solids = [xformBase.inputParams.featureID];
|
|
94
|
+
xform.inputParams.translate = [2, 0, 0];
|
|
95
|
+
xform.inputParams.rotateEulerDeg = [0, 0, 45];
|
|
96
|
+
xform.inputParams.copy = true;
|
|
97
|
+
|
|
98
|
+
const overlapBase = await partHistory.newFeature("P.CU");
|
|
99
|
+
const overlap = await partHistory.newFeature("OVL");
|
|
100
|
+
overlap.inputParams.targetSolid = overlapBase.inputParams.featureID;
|
|
101
|
+
overlap.inputParams.distance = 0.0005;
|
|
102
|
+
|
|
103
|
+
const patLinBase = await partHistory.newFeature("P.CU");
|
|
104
|
+
const patLin = await partHistory.newFeature("PATLIN");
|
|
105
|
+
patLin.inputParams.solids = [patLinBase.inputParams.featureID];
|
|
106
|
+
patLin.inputParams.count = 3;
|
|
107
|
+
patLin.inputParams.offset = { position: [3, 0, 0], rotationEuler: [0, 0, 0], scale: [1, 1, 1] };
|
|
108
|
+
|
|
109
|
+
const patRadBase = await partHistory.newFeature("P.CU");
|
|
110
|
+
const patRad = await partHistory.newFeature("PATRAD");
|
|
111
|
+
patRad.inputParams.solids = [patRadBase.inputParams.featureID];
|
|
112
|
+
patRad.inputParams.axisRef = axisEdgeName;
|
|
113
|
+
patRad.inputParams.count = 4;
|
|
114
|
+
patRad.inputParams.totalAngleDeg = 180;
|
|
115
|
+
|
|
116
|
+
const patLegacyBase = await partHistory.newFeature("P.CU");
|
|
117
|
+
const patLegacy = await partHistory.newFeature("PATTERN");
|
|
118
|
+
patLegacy.inputParams.solids = [patLegacyBase.inputParams.featureID];
|
|
119
|
+
patLegacy.inputParams.mode = "LINEAR";
|
|
120
|
+
patLegacy.inputParams.count = 2;
|
|
121
|
+
|
|
122
|
+
const acomp = await partHistory.newFeature("ACOMP");
|
|
123
|
+
acomp.inputParams.componentName = "missing_component";
|
|
124
|
+
|
|
125
|
+
const image = await partHistory.newFeature("IMAGE");
|
|
126
|
+
image.inputParams.fileToImport = "";
|
|
127
|
+
|
|
128
|
+
const heightmap = await partHistory.newFeature("HEIGHTMAP");
|
|
129
|
+
heightmap.inputParams.fileToImport = "";
|
|
130
|
+
|
|
131
|
+
return partHistory;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export async function afterRun_history_features_basic(partHistory) {
|
|
135
|
+
const requireFeatureObject = (type, label) => {
|
|
136
|
+
const entry = partHistory.features.find((f) => f?.type === type);
|
|
137
|
+
if (!entry) throw new Error(`${label} feature missing from history`);
|
|
138
|
+
const fid = entry?.inputParams?.featureID;
|
|
139
|
+
if (!fid) throw new Error(`${label} feature missing featureID`);
|
|
140
|
+
const obj = partHistory.scene.getObjectByName(fid);
|
|
141
|
+
if (!obj) throw new Error(`${label} object not found in scene`);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
requireFeatureObject("D", "Datium");
|
|
145
|
+
requireFeatureObject("SP", "Spline");
|
|
146
|
+
requireFeatureObject("HX", "Helix");
|
|
147
|
+
requireFeatureObject("LOFT", "Loft");
|
|
148
|
+
requireFeatureObject("R", "Revolve");
|
|
149
|
+
}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
const CUBE_SIZE = 12;
|
|
2
|
+
const HOLE_DIAMETER = 2;
|
|
3
|
+
const CSK_DIAMETER = 6;
|
|
4
|
+
const CSK_ANGLE = 90;
|
|
5
|
+
const CSK_DEPTH = 6;
|
|
6
|
+
const CBORE_DIAMETER = 6;
|
|
7
|
+
const CBORE_DEPTH = 3;
|
|
8
|
+
const CBORE_TOTAL_DEPTH = 7;
|
|
9
|
+
const EPS = 1e-6;
|
|
10
|
+
|
|
11
|
+
function buildSketchWithPoints(sketchFeature, points) {
|
|
12
|
+
const pointList = [
|
|
13
|
+
{ id: 0, x: 0, y: 0, fixed: true },
|
|
14
|
+
...points.map((p, idx) => ({
|
|
15
|
+
id: idx + 1,
|
|
16
|
+
x: p[0],
|
|
17
|
+
y: p[1],
|
|
18
|
+
fixed: false,
|
|
19
|
+
})),
|
|
20
|
+
];
|
|
21
|
+
sketchFeature.persistentData.sketch = {
|
|
22
|
+
points: pointList,
|
|
23
|
+
geometries: [],
|
|
24
|
+
constraints: [{ id: 0, type: "⏚", points: [0] }],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function findHoleFeature(partHistory) {
|
|
29
|
+
return partHistory.features.find((f) => f?.type === "H") || null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function countHoleMetadata(solids) {
|
|
33
|
+
let count = 0;
|
|
34
|
+
for (const solid of solids) {
|
|
35
|
+
const meta = solid?._faceMetadata;
|
|
36
|
+
if (!(meta instanceof Map)) continue;
|
|
37
|
+
for (const value of meta.values()) {
|
|
38
|
+
if (value?.hole) count++;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return count;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getPrimarySolid(partHistory) {
|
|
45
|
+
const solids = (partHistory.scene?.children || []).filter((o) => o?.type === "SOLID");
|
|
46
|
+
return solids[0] || null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function expectApprox(value, expected, label) {
|
|
50
|
+
if (!Number.isFinite(value) || Math.abs(value - expected) > EPS) {
|
|
51
|
+
throw new Error(`${label} expected ${expected}, got ${value}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function test_hole_through(partHistory) {
|
|
56
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
57
|
+
cube.inputParams.sizeX = CUBE_SIZE;
|
|
58
|
+
cube.inputParams.sizeY = CUBE_SIZE;
|
|
59
|
+
cube.inputParams.sizeZ = CUBE_SIZE;
|
|
60
|
+
|
|
61
|
+
const plane = await partHistory.newFeature("P");
|
|
62
|
+
plane.inputParams.orientation = "XY";
|
|
63
|
+
|
|
64
|
+
const sketch = await partHistory.newFeature("S");
|
|
65
|
+
sketch.inputParams.sketchPlane = plane.inputParams.featureID;
|
|
66
|
+
buildSketchWithPoints(sketch, [[CUBE_SIZE * 0.5, CUBE_SIZE * 0.5]]);
|
|
67
|
+
|
|
68
|
+
const hole = await partHistory.newFeature("H");
|
|
69
|
+
hole.inputParams.face = sketch.inputParams.featureID;
|
|
70
|
+
hole.inputParams.holeType = "SIMPLE";
|
|
71
|
+
hole.inputParams.diameter = HOLE_DIAMETER;
|
|
72
|
+
hole.inputParams.throughAll = true;
|
|
73
|
+
hole.inputParams.boolean = {
|
|
74
|
+
targets: [cube.inputParams.featureID],
|
|
75
|
+
operation: "SUBTRACT",
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return partHistory;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function afterRun_hole_through(partHistory) {
|
|
82
|
+
const holeFeature = findHoleFeature(partHistory);
|
|
83
|
+
if (!holeFeature) throw new Error("[hole_through] Hole feature missing");
|
|
84
|
+
const holes = holeFeature.persistentData?.holes || [];
|
|
85
|
+
if (!holes.length) throw new Error("[hole_through] No hole records");
|
|
86
|
+
if (!holes[0]?.throughAll) throw new Error("[hole_through] Expected through-all hole record");
|
|
87
|
+
if (String(holes[0]?.type || "").toUpperCase() !== "SIMPLE") {
|
|
88
|
+
throw new Error(`[hole_through] Expected SIMPLE hole, got ${holes[0]?.type}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const solid = getPrimarySolid(partHistory);
|
|
92
|
+
if (!solid) throw new Error("[hole_through] No solids created");
|
|
93
|
+
const faceCount = solid._faceNameToID?.size || 0;
|
|
94
|
+
if (faceCount <= 6) throw new Error("[hole_through] Hole did not add faces");
|
|
95
|
+
|
|
96
|
+
const holeMetaCount = countHoleMetadata([solid]);
|
|
97
|
+
if (holeMetaCount === 0) throw new Error("[hole_through] No hole face metadata found");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export async function test_hole_thread_symbolic(partHistory) {
|
|
101
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
102
|
+
cube.inputParams.sizeX = CUBE_SIZE;
|
|
103
|
+
cube.inputParams.sizeY = CUBE_SIZE;
|
|
104
|
+
cube.inputParams.sizeZ = CUBE_SIZE;
|
|
105
|
+
|
|
106
|
+
const plane = await partHistory.newFeature("P");
|
|
107
|
+
plane.inputParams.orientation = "XY";
|
|
108
|
+
|
|
109
|
+
const sketch = await partHistory.newFeature("S");
|
|
110
|
+
sketch.inputParams.sketchPlane = plane.inputParams.featureID;
|
|
111
|
+
buildSketchWithPoints(sketch, [[CUBE_SIZE * 0.35, CUBE_SIZE * 0.35]]);
|
|
112
|
+
|
|
113
|
+
const hole = await partHistory.newFeature("H");
|
|
114
|
+
hole.inputParams.face = sketch.inputParams.featureID;
|
|
115
|
+
hole.inputParams.holeType = "THREADED";
|
|
116
|
+
hole.inputParams.depth = 6;
|
|
117
|
+
hole.inputParams.throughAll = false;
|
|
118
|
+
hole.inputParams.threadStandard = "ISO_METRIC";
|
|
119
|
+
hole.inputParams.threadDesignation = "M6x1";
|
|
120
|
+
hole.inputParams.threadMode = "SYMBOLIC";
|
|
121
|
+
hole.inputParams.boolean = {
|
|
122
|
+
targets: [cube.inputParams.featureID],
|
|
123
|
+
operation: "SUBTRACT",
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return partHistory;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function afterRun_hole_thread_symbolic(partHistory) {
|
|
130
|
+
const holeFeature = findHoleFeature(partHistory);
|
|
131
|
+
if (!holeFeature) throw new Error("[hole_thread_symbolic] Hole feature missing");
|
|
132
|
+
const holes = holeFeature.persistentData?.holes || [];
|
|
133
|
+
if (!holes.length) throw new Error("[hole_thread_symbolic] No hole records");
|
|
134
|
+
const record = holes[0];
|
|
135
|
+
if (String(record?.type || "").toUpperCase() !== "THREADED") {
|
|
136
|
+
throw new Error(`[hole_thread_symbolic] Expected THREADED hole, got ${record?.type}`);
|
|
137
|
+
}
|
|
138
|
+
if (!record?.thread || String(record.thread.mode || "").toUpperCase() !== "SYMBOLIC") {
|
|
139
|
+
throw new Error("[hole_thread_symbolic] Expected symbolic thread metadata");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export async function test_hole_thread_modeled(partHistory) {
|
|
144
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
145
|
+
cube.inputParams.sizeX = CUBE_SIZE;
|
|
146
|
+
cube.inputParams.sizeY = CUBE_SIZE;
|
|
147
|
+
cube.inputParams.sizeZ = CUBE_SIZE;
|
|
148
|
+
|
|
149
|
+
const plane = await partHistory.newFeature("P");
|
|
150
|
+
plane.inputParams.orientation = "XY";
|
|
151
|
+
|
|
152
|
+
const sketch = await partHistory.newFeature("S");
|
|
153
|
+
sketch.inputParams.sketchPlane = plane.inputParams.featureID;
|
|
154
|
+
buildSketchWithPoints(sketch, [[CUBE_SIZE * 0.65, CUBE_SIZE * 0.35]]);
|
|
155
|
+
|
|
156
|
+
const hole = await partHistory.newFeature("H");
|
|
157
|
+
hole.inputParams.face = sketch.inputParams.featureID;
|
|
158
|
+
hole.inputParams.holeType = "THREADED";
|
|
159
|
+
hole.inputParams.depth = 4;
|
|
160
|
+
hole.inputParams.throughAll = false;
|
|
161
|
+
hole.inputParams.threadStandard = "ISO_METRIC";
|
|
162
|
+
hole.inputParams.threadDesignation = "M6x1";
|
|
163
|
+
hole.inputParams.threadMode = "MODELED";
|
|
164
|
+
hole.inputParams.boolean = {
|
|
165
|
+
targets: [cube.inputParams.featureID],
|
|
166
|
+
operation: "SUBTRACT",
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
return partHistory;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function afterRun_hole_thread_modeled(partHistory) {
|
|
173
|
+
const holeFeature = findHoleFeature(partHistory);
|
|
174
|
+
if (!holeFeature) throw new Error("[hole_thread_modeled] Hole feature missing");
|
|
175
|
+
const holes = holeFeature.persistentData?.holes || [];
|
|
176
|
+
if (!holes.length) throw new Error("[hole_thread_modeled] No hole records");
|
|
177
|
+
const record = holes[0];
|
|
178
|
+
if (String(record?.type || "").toUpperCase() !== "THREADED") {
|
|
179
|
+
throw new Error(`[hole_thread_modeled] Expected THREADED hole, got ${record?.type}`);
|
|
180
|
+
}
|
|
181
|
+
if (!record?.thread || String(record.thread.mode || "").toUpperCase() !== "MODELED") {
|
|
182
|
+
throw new Error("[hole_thread_modeled] Expected modeled thread metadata");
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export async function test_hole_countersink(partHistory) {
|
|
187
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
188
|
+
cube.inputParams.sizeX = CUBE_SIZE;
|
|
189
|
+
cube.inputParams.sizeY = CUBE_SIZE;
|
|
190
|
+
cube.inputParams.sizeZ = CUBE_SIZE;
|
|
191
|
+
|
|
192
|
+
const plane = await partHistory.newFeature("P");
|
|
193
|
+
plane.inputParams.orientation = "XY";
|
|
194
|
+
|
|
195
|
+
const sketch = await partHistory.newFeature("S");
|
|
196
|
+
sketch.inputParams.sketchPlane = plane.inputParams.featureID;
|
|
197
|
+
buildSketchWithPoints(sketch, [[CUBE_SIZE * 0.25, CUBE_SIZE * 0.65]]);
|
|
198
|
+
|
|
199
|
+
const hole = await partHistory.newFeature("H");
|
|
200
|
+
hole.inputParams.face = sketch.inputParams.featureID;
|
|
201
|
+
hole.inputParams.holeType = "COUNTERSINK";
|
|
202
|
+
hole.inputParams.diameter = HOLE_DIAMETER;
|
|
203
|
+
hole.inputParams.depth = CSK_DEPTH;
|
|
204
|
+
hole.inputParams.throughAll = false;
|
|
205
|
+
hole.inputParams.countersinkDiameter = CSK_DIAMETER;
|
|
206
|
+
hole.inputParams.countersinkAngle = CSK_ANGLE;
|
|
207
|
+
hole.inputParams.boolean = {
|
|
208
|
+
targets: [cube.inputParams.featureID],
|
|
209
|
+
operation: "SUBTRACT",
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
return partHistory;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export async function afterRun_hole_countersink(partHistory) {
|
|
216
|
+
const holeFeature = findHoleFeature(partHistory);
|
|
217
|
+
if (!holeFeature) throw new Error("[hole_countersink] Hole feature missing");
|
|
218
|
+
const holes = holeFeature.persistentData?.holes || [];
|
|
219
|
+
if (!holes.length) throw new Error("[hole_countersink] No hole records");
|
|
220
|
+
const record = holes[0];
|
|
221
|
+
if (String(record?.type || "").toUpperCase() !== "COUNTERSINK") {
|
|
222
|
+
throw new Error(`[hole_countersink] Expected COUNTERSINK hole, got ${record?.type}`);
|
|
223
|
+
}
|
|
224
|
+
if (record?.throughAll) throw new Error("[hole_countersink] Expected non-through hole");
|
|
225
|
+
if (!(record?.countersinkHeight > 0)) throw new Error("[hole_countersink] Expected countersink height > 0");
|
|
226
|
+
expectApprox(record?.countersinkDiameter, CSK_DIAMETER, "[hole_countersink] countersink diameter");
|
|
227
|
+
expectApprox(record?.countersinkAngle, CSK_ANGLE, "[hole_countersink] countersink angle");
|
|
228
|
+
|
|
229
|
+
const solid = getPrimarySolid(partHistory);
|
|
230
|
+
if (!solid) throw new Error("[hole_countersink] No solids created");
|
|
231
|
+
const holeMetaCount = countHoleMetadata([solid]);
|
|
232
|
+
if (holeMetaCount === 0) throw new Error("[hole_countersink] No hole face metadata found");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export async function test_hole_counterbore(partHistory) {
|
|
236
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
237
|
+
cube.inputParams.sizeX = CUBE_SIZE;
|
|
238
|
+
cube.inputParams.sizeY = CUBE_SIZE;
|
|
239
|
+
cube.inputParams.sizeZ = CUBE_SIZE;
|
|
240
|
+
|
|
241
|
+
const plane = await partHistory.newFeature("P");
|
|
242
|
+
plane.inputParams.orientation = "XY";
|
|
243
|
+
|
|
244
|
+
const sketch = await partHistory.newFeature("S");
|
|
245
|
+
sketch.inputParams.sketchPlane = plane.inputParams.featureID;
|
|
246
|
+
buildSketchWithPoints(sketch, [[CUBE_SIZE * 0.75, CUBE_SIZE * 0.65]]);
|
|
247
|
+
|
|
248
|
+
const hole = await partHistory.newFeature("H");
|
|
249
|
+
hole.inputParams.face = sketch.inputParams.featureID;
|
|
250
|
+
hole.inputParams.holeType = "COUNTERBORE";
|
|
251
|
+
hole.inputParams.diameter = HOLE_DIAMETER;
|
|
252
|
+
hole.inputParams.depth = CBORE_TOTAL_DEPTH;
|
|
253
|
+
hole.inputParams.throughAll = false;
|
|
254
|
+
hole.inputParams.counterboreDiameter = CBORE_DIAMETER;
|
|
255
|
+
hole.inputParams.counterboreDepth = CBORE_DEPTH;
|
|
256
|
+
hole.inputParams.boolean = {
|
|
257
|
+
targets: [cube.inputParams.featureID],
|
|
258
|
+
operation: "SUBTRACT",
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
return partHistory;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export async function afterRun_hole_counterbore(partHistory) {
|
|
265
|
+
const holeFeature = findHoleFeature(partHistory);
|
|
266
|
+
if (!holeFeature) throw new Error("[hole_counterbore] Hole feature missing");
|
|
267
|
+
const holes = holeFeature.persistentData?.holes || [];
|
|
268
|
+
if (!holes.length) throw new Error("[hole_counterbore] No hole records");
|
|
269
|
+
const record = holes[0];
|
|
270
|
+
if (String(record?.type || "").toUpperCase() !== "COUNTERBORE") {
|
|
271
|
+
throw new Error(`[hole_counterbore] Expected COUNTERBORE hole, got ${record?.type}`);
|
|
272
|
+
}
|
|
273
|
+
if (record?.throughAll) throw new Error("[hole_counterbore] Expected non-through hole");
|
|
274
|
+
expectApprox(record?.counterboreDiameter, CBORE_DIAMETER, "[hole_counterbore] counterbore diameter");
|
|
275
|
+
expectApprox(record?.counterboreDepth, CBORE_DEPTH, "[hole_counterbore] counterbore depth");
|
|
276
|
+
expectApprox(record?.straightDepth, CBORE_TOTAL_DEPTH - CBORE_DEPTH, "[hole_counterbore] straight depth");
|
|
277
|
+
|
|
278
|
+
const solid = getPrimarySolid(partHistory);
|
|
279
|
+
if (!solid) throw new Error("[hole_counterbore] No solids created");
|
|
280
|
+
const holeMetaCount = countHoleMetadata([solid]);
|
|
281
|
+
if (holeMetaCount === 0) throw new Error("[hole_counterbore] No hole face metadata found");
|
|
282
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export async function test_mirror(partHistory) {
|
|
2
|
+
// Create a base cube to mirror
|
|
3
|
+
const cube = await partHistory.newFeature("P.CU");
|
|
4
|
+
cube.inputParams.sizeX = 4;
|
|
5
|
+
cube.inputParams.sizeY = 3;
|
|
6
|
+
cube.inputParams.sizeZ = 2;
|
|
7
|
+
|
|
8
|
+
// Mirror the cube across one of its own faces (PX face plane)
|
|
9
|
+
const mirror = await partHistory.newFeature("M");
|
|
10
|
+
mirror.inputParams.solids = [cube.inputParams.featureID];
|
|
11
|
+
mirror.inputParams.mirrorPlane = `${cube.inputParams.featureID}_PX`;
|
|
12
|
+
mirror.inputParams.offsetDistance = 0; // on-face mirror
|
|
13
|
+
|
|
14
|
+
return partHistory;
|
|
15
|
+
}
|
|
16
|
+
|