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.
Files changed (403) hide show
  1. package/LICENSE.md +32 -0
  2. package/README.md +144 -0
  3. package/dist-kernel/brep-kernel.js +74699 -0
  4. package/dist-kernel/help/CONTRIBUTING.html +248 -0
  5. package/dist-kernel/help/LICENSE.html +248 -0
  6. package/dist-kernel/help/MODELING.png +0 -0
  7. package/dist-kernel/help/PMI.png +0 -0
  8. package/dist-kernel/help/SKETCH.png +0 -0
  9. package/dist-kernel/help/assembly-constraints__Coincident_Constraint_dialog.png +0 -0
  10. package/dist-kernel/help/assembly-constraints___Angle_Constraint_dialog.png +0 -0
  11. package/dist-kernel/help/assembly-constraints___Distance_Constraint_dialog.png +0 -0
  12. package/dist-kernel/help/assembly-constraints___Fixed_Constraint_dialog.png +0 -0
  13. package/dist-kernel/help/assembly-constraints___Parallel_Constraint_dialog.png +0 -0
  14. package/dist-kernel/help/assembly-constraints___Touch_Align_Constraint_dialog.png +0 -0
  15. package/dist-kernel/help/assembly-constraints__angle-constraint.html +248 -0
  16. package/dist-kernel/help/assembly-constraints__coincident-constraint.html +248 -0
  17. package/dist-kernel/help/assembly-constraints__distance-constraint.html +248 -0
  18. package/dist-kernel/help/assembly-constraints__fixed-constraint.html +248 -0
  19. package/dist-kernel/help/assembly-constraints__parallel-constraint.html +248 -0
  20. package/dist-kernel/help/assembly-constraints__solver.html +248 -0
  21. package/dist-kernel/help/assembly-constraints__touch-align-constraint.html +248 -0
  22. package/dist-kernel/help/brep-api.html +263 -0
  23. package/dist-kernel/help/brep-kernel.html +258 -0
  24. package/dist-kernel/help/brep-model.html +248 -0
  25. package/dist-kernel/help/cylindrical-face-radius-embedding.html +290 -0
  26. package/dist-kernel/help/dialog-screenshots.html +248 -0
  27. package/dist-kernel/help/extruded-sketch-radius-embedding.html +336 -0
  28. package/dist-kernel/help/features__Assembly_Component_dialog.png +0 -0
  29. package/dist-kernel/help/features__Boolean_dialog.png +0 -0
  30. package/dist-kernel/help/features__Chamfer_dialog.png +0 -0
  31. package/dist-kernel/help/features__Datium_dialog.png +0 -0
  32. package/dist-kernel/help/features__Extrude_dialog.png +0 -0
  33. package/dist-kernel/help/features__Fillet_dialog.png +0 -0
  34. package/dist-kernel/help/features__Helix_dialog.png +0 -0
  35. package/dist-kernel/help/features__Hole_dialog.png +0 -0
  36. package/dist-kernel/help/features__Image_Heightmap_Solid_dialog.png +0 -0
  37. package/dist-kernel/help/features__Image_to_Face_dialog.png +0 -0
  38. package/dist-kernel/help/features__Import_3D_Model_dialog.png +0 -0
  39. package/dist-kernel/help/features__Loft_dialog.png +0 -0
  40. package/dist-kernel/help/features__Mirror_dialog.png +0 -0
  41. package/dist-kernel/help/features__Offset_Shell_dialog.png +0 -0
  42. package/dist-kernel/help/features__Overlap_Cleanup_dialog.png +0 -0
  43. package/dist-kernel/help/features__Pattern_Linear_dialog.png +0 -0
  44. package/dist-kernel/help/features__Pattern_Radial_dialog.png +0 -0
  45. package/dist-kernel/help/features__Pattern_dialog.png +0 -0
  46. package/dist-kernel/help/features__Plane_dialog.png +0 -0
  47. package/dist-kernel/help/features__Primitive_Cone_dialog.png +0 -0
  48. package/dist-kernel/help/features__Primitive_Cube_dialog.png +0 -0
  49. package/dist-kernel/help/features__Primitive_Cylinder_dialog.png +0 -0
  50. package/dist-kernel/help/features__Primitive_Pyramid_dialog.png +0 -0
  51. package/dist-kernel/help/features__Primitive_Sphere_dialog.png +0 -0
  52. package/dist-kernel/help/features__Primitive_Torus_dialog.png +0 -0
  53. package/dist-kernel/help/features__Remesh_dialog.png +0 -0
  54. package/dist-kernel/help/features__Revolve_dialog.png +0 -0
  55. package/dist-kernel/help/features__Sheet_Metal_Contour_Flange_dialog.png +0 -0
  56. package/dist-kernel/help/features__Sheet_Metal_Cutout_dialog.png +0 -0
  57. package/dist-kernel/help/features__Sheet_Metal_Flange_dialog.png +0 -0
  58. package/dist-kernel/help/features__Sheet_Metal_Tab_dialog.png +0 -0
  59. package/dist-kernel/help/features__Sketch_dialog.png +0 -0
  60. package/dist-kernel/help/features__Spline_dialog.png +0 -0
  61. package/dist-kernel/help/features__Sweep_dialog.png +0 -0
  62. package/dist-kernel/help/features__Transform_dialog.png +0 -0
  63. package/dist-kernel/help/features__Tube_dialog.png +0 -0
  64. package/dist-kernel/help/features__assembly-component.html +248 -0
  65. package/dist-kernel/help/features__boolean.html +248 -0
  66. package/dist-kernel/help/features__chamfer.html +248 -0
  67. package/dist-kernel/help/features__datium.html +248 -0
  68. package/dist-kernel/help/features__datum.html +248 -0
  69. package/dist-kernel/help/features__extrude.html +248 -0
  70. package/dist-kernel/help/features__fillet.html +248 -0
  71. package/dist-kernel/help/features__helix.html +248 -0
  72. package/dist-kernel/help/features__hole.html +248 -0
  73. package/dist-kernel/help/features__image-heightmap-solid.html +248 -0
  74. package/dist-kernel/help/features__image-to-face-2D_dialog.png +0 -0
  75. package/dist-kernel/help/features__image-to-face-3D_dialog.png +0 -0
  76. package/dist-kernel/help/features__image-to-face.html +248 -0
  77. package/dist-kernel/help/features__import-3d-model.html +248 -0
  78. package/dist-kernel/help/features__index.html +248 -0
  79. package/dist-kernel/help/features__loft.html +248 -0
  80. package/dist-kernel/help/features__mirror.html +248 -0
  81. package/dist-kernel/help/features__offset-shell.html +248 -0
  82. package/dist-kernel/help/features__pattern-linear.html +248 -0
  83. package/dist-kernel/help/features__pattern-radial.html +248 -0
  84. package/dist-kernel/help/features__pattern.html +248 -0
  85. package/dist-kernel/help/features__plane.html +248 -0
  86. package/dist-kernel/help/features__primitive-cone.html +248 -0
  87. package/dist-kernel/help/features__primitive-cube.html +248 -0
  88. package/dist-kernel/help/features__primitive-cylinder.html +248 -0
  89. package/dist-kernel/help/features__primitive-pyramid.html +248 -0
  90. package/dist-kernel/help/features__primitive-sphere.html +248 -0
  91. package/dist-kernel/help/features__primitive-torus.html +248 -0
  92. package/dist-kernel/help/features__remesh.html +248 -0
  93. package/dist-kernel/help/features__revolve.html +248 -0
  94. package/dist-kernel/help/features__sheet-metal-contour-flange.html +248 -0
  95. package/dist-kernel/help/features__sheet-metal-flange.html +248 -0
  96. package/dist-kernel/help/features__sheet-metal-tab.html +248 -0
  97. package/dist-kernel/help/features__sketch.html +248 -0
  98. package/dist-kernel/help/features__spline.html +248 -0
  99. package/dist-kernel/help/features__sweep.html +248 -0
  100. package/dist-kernel/help/features__transform.html +248 -0
  101. package/dist-kernel/help/features__tube.html +248 -0
  102. package/dist-kernel/help/file-formats.html +248 -0
  103. package/dist-kernel/help/getting-started.html +248 -0
  104. package/dist-kernel/help/highlights.html +248 -0
  105. package/dist-kernel/help/history-systems.html +248 -0
  106. package/dist-kernel/help/how-it-works.html +248 -0
  107. package/dist-kernel/help/index.html +862 -0
  108. package/dist-kernel/help/input-params-schema.html +363 -0
  109. package/dist-kernel/help/inspector-improvements.html +248 -0
  110. package/dist-kernel/help/inspector.html +248 -0
  111. package/dist-kernel/help/modes__modeling.html +248 -0
  112. package/dist-kernel/help/modes__pmi.html +248 -0
  113. package/dist-kernel/help/modes__sketch.html +248 -0
  114. package/dist-kernel/help/plugins.html +248 -0
  115. package/dist-kernel/help/pmi-annotations__Angle_Dimension_dialog.png +0 -0
  116. package/dist-kernel/help/pmi-annotations__Explode_Body_dialog.png +0 -0
  117. package/dist-kernel/help/pmi-annotations__Hole_Callout_dialog.png +0 -0
  118. package/dist-kernel/help/pmi-annotations__Leader_dialog.png +0 -0
  119. package/dist-kernel/help/pmi-annotations__Linear_Dimension_dialog.png +0 -0
  120. package/dist-kernel/help/pmi-annotations__Note_dialog.png +0 -0
  121. package/dist-kernel/help/pmi-annotations__Radial_Dimension_dialog.png +0 -0
  122. package/dist-kernel/help/pmi-annotations__angle-dimension.html +248 -0
  123. package/dist-kernel/help/pmi-annotations__explode-body.html +248 -0
  124. package/dist-kernel/help/pmi-annotations__hole-callout.html +248 -0
  125. package/dist-kernel/help/pmi-annotations__index.html +248 -0
  126. package/dist-kernel/help/pmi-annotations__leader.html +248 -0
  127. package/dist-kernel/help/pmi-annotations__linear-dimension.html +248 -0
  128. package/dist-kernel/help/pmi-annotations__note.html +248 -0
  129. package/dist-kernel/help/pmi-annotations__radial-dimension.html +248 -0
  130. package/dist-kernel/help/search-index.json +464 -0
  131. package/dist-kernel/help/simplified-radial-dimensions.html +298 -0
  132. package/dist-kernel/help/solid-methods.html +359 -0
  133. package/dist-kernel/help/table-of-contents.html +330 -0
  134. package/dist-kernel/help/ui-overview.html +248 -0
  135. package/dist-kernel/help/whats-new.html +248 -0
  136. package/package.json +54 -0
  137. package/src/BREP/AssemblyComponent.js +42 -0
  138. package/src/BREP/BREP.js +43 -0
  139. package/src/BREP/BetterSolid.js +805 -0
  140. package/src/BREP/Edge.js +103 -0
  141. package/src/BREP/Extrude.js +403 -0
  142. package/src/BREP/Face.js +187 -0
  143. package/src/BREP/MeshRepairer.js +634 -0
  144. package/src/BREP/OffsetShellSolid.js +614 -0
  145. package/src/BREP/PointCloudWrap.js +302 -0
  146. package/src/BREP/Revolve.js +345 -0
  147. package/src/BREP/SolidMethods/authoring.js +112 -0
  148. package/src/BREP/SolidMethods/booleanOps.js +230 -0
  149. package/src/BREP/SolidMethods/chamfer.js +122 -0
  150. package/src/BREP/SolidMethods/edgeResolution.js +25 -0
  151. package/src/BREP/SolidMethods/fillet.js +792 -0
  152. package/src/BREP/SolidMethods/index.js +72 -0
  153. package/src/BREP/SolidMethods/io.js +105 -0
  154. package/src/BREP/SolidMethods/lifecycle.js +103 -0
  155. package/src/BREP/SolidMethods/manifoldOps.js +375 -0
  156. package/src/BREP/SolidMethods/meshCleanup.js +2512 -0
  157. package/src/BREP/SolidMethods/meshQueries.js +264 -0
  158. package/src/BREP/SolidMethods/metadata.js +106 -0
  159. package/src/BREP/SolidMethods/metrics.js +51 -0
  160. package/src/BREP/SolidMethods/transforms.js +361 -0
  161. package/src/BREP/SolidMethods/visualize.js +508 -0
  162. package/src/BREP/SolidShared.js +26 -0
  163. package/src/BREP/Sweep.js +1596 -0
  164. package/src/BREP/Tube.js +857 -0
  165. package/src/BREP/Vertex.js +43 -0
  166. package/src/BREP/applyBooleanOperation.js +704 -0
  167. package/src/BREP/boundsUtils.js +48 -0
  168. package/src/BREP/chamfer.js +551 -0
  169. package/src/BREP/edgePolylineUtils.js +85 -0
  170. package/src/BREP/fillets/common.js +388 -0
  171. package/src/BREP/fillets/fillet.js +1422 -0
  172. package/src/BREP/fillets/filletGeometry.js +15 -0
  173. package/src/BREP/fillets/inset.js +389 -0
  174. package/src/BREP/fillets/offsetHelper.js +143 -0
  175. package/src/BREP/fillets/outset.js +88 -0
  176. package/src/BREP/helix.js +193 -0
  177. package/src/BREP/meshToBrep.js +234 -0
  178. package/src/BREP/primitives.js +279 -0
  179. package/src/BREP/setupManifold.js +71 -0
  180. package/src/BREP/threadGeometry.js +1120 -0
  181. package/src/BREP/triangleUtils.js +8 -0
  182. package/src/BREP/triangulate.js +608 -0
  183. package/src/FeatureRegistry.js +183 -0
  184. package/src/PartHistory.js +1132 -0
  185. package/src/UI/AccordionWidget.js +292 -0
  186. package/src/UI/CADmaterials.js +850 -0
  187. package/src/UI/EnvMonacoEditor.js +522 -0
  188. package/src/UI/FloatingWindow.js +396 -0
  189. package/src/UI/HistoryWidget.js +457 -0
  190. package/src/UI/MainToolbar.js +131 -0
  191. package/src/UI/ModelLibraryView.js +194 -0
  192. package/src/UI/OrthoCameraIdle.js +206 -0
  193. package/src/UI/PluginsWidget.js +280 -0
  194. package/src/UI/SceneListing.js +606 -0
  195. package/src/UI/SelectionFilter.js +629 -0
  196. package/src/UI/ViewCube.js +389 -0
  197. package/src/UI/assembly/AssemblyConstraintCollectionWidget.js +329 -0
  198. package/src/UI/assembly/AssemblyConstraintControlsWidget.js +282 -0
  199. package/src/UI/assembly/AssemblyConstraintsWidget.css +292 -0
  200. package/src/UI/assembly/AssemblyConstraintsWidget.js +1373 -0
  201. package/src/UI/assembly/constraintFaceUtils.js +115 -0
  202. package/src/UI/assembly/constraintHighlightUtils.js +70 -0
  203. package/src/UI/assembly/constraintLabelUtils.js +31 -0
  204. package/src/UI/assembly/constraintPointUtils.js +64 -0
  205. package/src/UI/assembly/constraintSelectionUtils.js +185 -0
  206. package/src/UI/assembly/constraintStatusUtils.js +142 -0
  207. package/src/UI/componentSelectorModal.js +240 -0
  208. package/src/UI/controls/CombinedTransformControls.js +386 -0
  209. package/src/UI/dialogs.js +351 -0
  210. package/src/UI/expressionsManager.js +100 -0
  211. package/src/UI/featureDialogWidgets/booleanField.js +25 -0
  212. package/src/UI/featureDialogWidgets/booleanOperationField.js +97 -0
  213. package/src/UI/featureDialogWidgets/buttonField.js +45 -0
  214. package/src/UI/featureDialogWidgets/componentSelectorField.js +102 -0
  215. package/src/UI/featureDialogWidgets/defaultField.js +23 -0
  216. package/src/UI/featureDialogWidgets/fileField.js +66 -0
  217. package/src/UI/featureDialogWidgets/index.js +34 -0
  218. package/src/UI/featureDialogWidgets/numberField.js +165 -0
  219. package/src/UI/featureDialogWidgets/optionsField.js +33 -0
  220. package/src/UI/featureDialogWidgets/referenceSelectionField.js +208 -0
  221. package/src/UI/featureDialogWidgets/stringField.js +24 -0
  222. package/src/UI/featureDialogWidgets/textareaField.js +28 -0
  223. package/src/UI/featureDialogWidgets/threadDesignationField.js +160 -0
  224. package/src/UI/featureDialogWidgets/transformField.js +252 -0
  225. package/src/UI/featureDialogWidgets/utils.js +43 -0
  226. package/src/UI/featureDialogWidgets/vec3Field.js +133 -0
  227. package/src/UI/featureDialogs.js +1414 -0
  228. package/src/UI/fileManagerWidget.js +615 -0
  229. package/src/UI/history/HistoryCollectionWidget.js +1294 -0
  230. package/src/UI/history/historyCollectionWidget.css.js +257 -0
  231. package/src/UI/history/historyDisplayInfo.js +133 -0
  232. package/src/UI/mobile.js +28 -0
  233. package/src/UI/objectDump.js +442 -0
  234. package/src/UI/pmi/AnnotationCollectionWidget.js +120 -0
  235. package/src/UI/pmi/AnnotationHistory.js +353 -0
  236. package/src/UI/pmi/AnnotationRegistry.js +90 -0
  237. package/src/UI/pmi/BaseAnnotation.js +269 -0
  238. package/src/UI/pmi/LabelOverlay.css +102 -0
  239. package/src/UI/pmi/LabelOverlay.js +191 -0
  240. package/src/UI/pmi/PMIMode.js +1550 -0
  241. package/src/UI/pmi/PMIViewsWidget.js +1098 -0
  242. package/src/UI/pmi/annUtils.js +729 -0
  243. package/src/UI/pmi/dimensions/AngleDimensionAnnotation.js +647 -0
  244. package/src/UI/pmi/dimensions/ExplodeBodyAnnotation.js +507 -0
  245. package/src/UI/pmi/dimensions/HoleCalloutAnnotation.js +462 -0
  246. package/src/UI/pmi/dimensions/LeaderAnnotation.js +403 -0
  247. package/src/UI/pmi/dimensions/LinearDimensionAnnotation.js +532 -0
  248. package/src/UI/pmi/dimensions/NoteAnnotation.js +110 -0
  249. package/src/UI/pmi/dimensions/RadialDimensionAnnotation.js +659 -0
  250. package/src/UI/pmi/pmiStyle.js +44 -0
  251. package/src/UI/sketcher/SketchMode3D.js +4095 -0
  252. package/src/UI/sketcher/dimensions.js +674 -0
  253. package/src/UI/sketcher/glyphs.js +236 -0
  254. package/src/UI/sketcher/highlights.js +60 -0
  255. package/src/UI/toolbarButtons/aboutButton.js +5 -0
  256. package/src/UI/toolbarButtons/exportButton.js +609 -0
  257. package/src/UI/toolbarButtons/flatPatternButton.js +307 -0
  258. package/src/UI/toolbarButtons/importButton.js +160 -0
  259. package/src/UI/toolbarButtons/inspectorToggleButton.js +12 -0
  260. package/src/UI/toolbarButtons/metadataButton.js +1063 -0
  261. package/src/UI/toolbarButtons/orientToFaceButton.js +114 -0
  262. package/src/UI/toolbarButtons/registerDefaultButtons.js +46 -0
  263. package/src/UI/toolbarButtons/saveButton.js +99 -0
  264. package/src/UI/toolbarButtons/scriptRunnerButton.js +302 -0
  265. package/src/UI/toolbarButtons/testsButton.js +26 -0
  266. package/src/UI/toolbarButtons/undoRedoButtons.js +25 -0
  267. package/src/UI/toolbarButtons/wireframeToggleButton.js +5 -0
  268. package/src/UI/toolbarButtons/zoomToFitButton.js +5 -0
  269. package/src/UI/triangleDebuggerWindow.js +945 -0
  270. package/src/UI/viewer.js +4228 -0
  271. package/src/assemblyConstraints/AssemblyConstraintHistory.js +1576 -0
  272. package/src/assemblyConstraints/AssemblyConstraintRegistry.js +120 -0
  273. package/src/assemblyConstraints/BaseAssemblyConstraint.js +66 -0
  274. package/src/assemblyConstraints/constraintExpressionUtils.js +35 -0
  275. package/src/assemblyConstraints/constraintUtils/parallelAlignment.js +676 -0
  276. package/src/assemblyConstraints/constraints/AngleConstraint.js +485 -0
  277. package/src/assemblyConstraints/constraints/CoincidentConstraint.js +194 -0
  278. package/src/assemblyConstraints/constraints/DistanceConstraint.js +616 -0
  279. package/src/assemblyConstraints/constraints/FixedConstraint.js +78 -0
  280. package/src/assemblyConstraints/constraints/ParallelConstraint.js +252 -0
  281. package/src/assemblyConstraints/constraints/TouchAlignConstraint.js +961 -0
  282. package/src/core/entities/HistoryCollectionBase.js +72 -0
  283. package/src/core/entities/ListEntityBase.js +109 -0
  284. package/src/core/entities/schemaProcesser.js +121 -0
  285. package/src/exporters/sheetMetalFlatPattern.js +659 -0
  286. package/src/exporters/sheetMetalUnfold.js +862 -0
  287. package/src/exporters/step.js +1135 -0
  288. package/src/exporters/threeMF.js +575 -0
  289. package/src/features/assemblyComponent/AssemblyComponentFeature.js +780 -0
  290. package/src/features/boolean/BooleanFeature.js +94 -0
  291. package/src/features/chamfer/ChamferFeature.js +116 -0
  292. package/src/features/datium/DatiumFeature.js +80 -0
  293. package/src/features/edgeFeatureUtils.js +41 -0
  294. package/src/features/extrude/ExtrudeFeature.js +143 -0
  295. package/src/features/fillet/FilletFeature.js +197 -0
  296. package/src/features/helix/HelixFeature.js +405 -0
  297. package/src/features/hole/HoleFeature.js +1050 -0
  298. package/src/features/hole/screwClearance.js +86 -0
  299. package/src/features/hole/threadDesignationCatalog.js +149 -0
  300. package/src/features/imageHeightSolid/ImageHeightmapSolidFeature.js +463 -0
  301. package/src/features/imageToFace/ImageToFaceFeature.js +727 -0
  302. package/src/features/imageToFace/imageEditor.js +1270 -0
  303. package/src/features/imageToFace/traceUtils.js +971 -0
  304. package/src/features/import3dModel/Import3dModelFeature.js +151 -0
  305. package/src/features/loft/LoftFeature.js +605 -0
  306. package/src/features/mirror/MirrorFeature.js +151 -0
  307. package/src/features/offsetFace/OffsetFaceFeature.js +370 -0
  308. package/src/features/offsetShell/OffsetShellFeature.js +89 -0
  309. package/src/features/overlapCleanup/OverlapCleanupFeature.js +85 -0
  310. package/src/features/pattern/PatternFeature.js +275 -0
  311. package/src/features/patternLinear/PatternLinearFeature.js +120 -0
  312. package/src/features/patternRadial/PatternRadialFeature.js +186 -0
  313. package/src/features/plane/PlaneFeature.js +154 -0
  314. package/src/features/primitiveCone/primitiveConeFeature.js +99 -0
  315. package/src/features/primitiveCube/primitiveCubeFeature.js +70 -0
  316. package/src/features/primitiveCylinder/primitiveCylinderFeature.js +91 -0
  317. package/src/features/primitivePyramid/primitivePyramidFeature.js +72 -0
  318. package/src/features/primitiveSphere/primitiveSphereFeature.js +62 -0
  319. package/src/features/primitiveTorus/primitiveTorusFeature.js +109 -0
  320. package/src/features/remesh/RemeshFeature.js +97 -0
  321. package/src/features/revolve/RevolveFeature.js +111 -0
  322. package/src/features/selectionUtils.js +118 -0
  323. package/src/features/sheetMetal/SheetMetalContourFlangeFeature.js +1656 -0
  324. package/src/features/sheetMetal/SheetMetalCutoutFeature.js +1056 -0
  325. package/src/features/sheetMetal/SheetMetalFlangeFeature.js +1568 -0
  326. package/src/features/sheetMetal/SheetMetalHemFeature.js +43 -0
  327. package/src/features/sheetMetal/SheetMetalObject.js +141 -0
  328. package/src/features/sheetMetal/SheetMetalTabFeature.js +176 -0
  329. package/src/features/sheetMetal/UNFOLD_NEUTRAL_REQUIREMENTS.md +153 -0
  330. package/src/features/sheetMetal/contour-flange-rebuild-spec.md +261 -0
  331. package/src/features/sheetMetal/profileUtils.js +25 -0
  332. package/src/features/sheetMetal/sheetMetalCleanup.js +9 -0
  333. package/src/features/sheetMetal/sheetMetalFaceTypes.js +146 -0
  334. package/src/features/sheetMetal/sheetMetalMetadata.js +165 -0
  335. package/src/features/sheetMetal/sheetMetalPipeline.js +169 -0
  336. package/src/features/sheetMetal/sheetMetalProfileUtils.js +216 -0
  337. package/src/features/sheetMetal/sheetMetalTabUtils.js +29 -0
  338. package/src/features/sheetMetal/sheetMetalTree.js +210 -0
  339. package/src/features/sketch/SketchFeature.js +955 -0
  340. package/src/features/sketch/sketchSolver2D/ConstraintEngine.js +800 -0
  341. package/src/features/sketch/sketchSolver2D/constraintDefinitions.js +704 -0
  342. package/src/features/sketch/sketchSolver2D/mathHelpersMod.js +307 -0
  343. package/src/features/spline/SplineEditorSession.js +988 -0
  344. package/src/features/spline/SplineFeature.js +1388 -0
  345. package/src/features/spline/splineUtils.js +218 -0
  346. package/src/features/sweep/SweepFeature.js +110 -0
  347. package/src/features/transform/TransformFeature.js +152 -0
  348. package/src/features/tube/TubeFeature.js +635 -0
  349. package/src/fs.proxy.js +625 -0
  350. package/src/idbStorage.js +254 -0
  351. package/src/index.js +12 -0
  352. package/src/main.js +15 -0
  353. package/src/metadataManager.js +64 -0
  354. package/src/path.proxy.js +277 -0
  355. package/src/plugins/ghLoader.worker.js +151 -0
  356. package/src/plugins/pluginManager.js +286 -0
  357. package/src/pmi/PMIViewsManager.js +134 -0
  358. package/src/services/componentLibrary.js +198 -0
  359. package/src/tests/ConsoleCapture.js +189 -0
  360. package/src/tests/S7-diagnostics-2025-12-23T18-37-23-570Z.json +630 -0
  361. package/src/tests/browserTests.js +597 -0
  362. package/src/tests/debugBoolean.js +225 -0
  363. package/src/tests/partFiles/badBoolean.json +957 -0
  364. package/src/tests/partFiles/extrudeTest.json +88 -0
  365. package/src/tests/partFiles/filletFail.json +58 -0
  366. package/src/tests/partFiles/import_TEst.part.part.json +646 -0
  367. package/src/tests/partFiles/sheetMetalHem.BREP.json +734 -0
  368. package/src/tests/test_boolean_subtract.js +27 -0
  369. package/src/tests/test_chamfer.js +17 -0
  370. package/src/tests/test_extrudeFace.js +24 -0
  371. package/src/tests/test_fillet.js +17 -0
  372. package/src/tests/test_fillet_nonClosed.js +45 -0
  373. package/src/tests/test_filletsMoreDifficult.js +46 -0
  374. package/src/tests/test_history_features_basic.js +149 -0
  375. package/src/tests/test_hole.js +282 -0
  376. package/src/tests/test_mirror.js +16 -0
  377. package/src/tests/test_offsetShellGrouping.js +85 -0
  378. package/src/tests/test_plane.js +4 -0
  379. package/src/tests/test_primitiveCone.js +11 -0
  380. package/src/tests/test_primitiveCube.js +7 -0
  381. package/src/tests/test_primitiveCylinder.js +8 -0
  382. package/src/tests/test_primitivePyramid.js +9 -0
  383. package/src/tests/test_primitiveSphere.js +17 -0
  384. package/src/tests/test_primitiveTorus.js +21 -0
  385. package/src/tests/test_pushFace.js +126 -0
  386. package/src/tests/test_sheetMetalContourFlange.js +125 -0
  387. package/src/tests/test_sheetMetal_features.js +80 -0
  388. package/src/tests/test_sketch_openLoop.js +45 -0
  389. package/src/tests/test_solidMetrics.js +58 -0
  390. package/src/tests/test_stlLoader.js +1889 -0
  391. package/src/tests/test_sweepFace.js +55 -0
  392. package/src/tests/test_tube.js +45 -0
  393. package/src/tests/test_tube_closedLoop.js +67 -0
  394. package/src/tests/tests.js +493 -0
  395. package/src/tools/assemblyConstraintDialogCapturePage.js +56 -0
  396. package/src/tools/dialogCapturePageFactory.js +227 -0
  397. package/src/tools/featureDialogCapturePage.js +47 -0
  398. package/src/tools/pmiAnnotationDialogCapturePage.js +60 -0
  399. package/src/utils/axisHelpers.js +99 -0
  400. package/src/utils/deepClone.js +69 -0
  401. package/src/utils/geometryTolerance.js +37 -0
  402. package/src/utils/normalizeTypeString.js +8 -0
  403. package/src/utils/xformMath.js +51 -0
@@ -0,0 +1,629 @@
1
+ import { CADmaterials } from "./CADmaterials.js";
2
+ import {BREP} from '../BREP/BREP.js';
3
+ export class SelectionFilter {
4
+ static SOLID = "SOLID";
5
+ static COMPONENT = "COMPONENT";
6
+ static FACE = "FACE";
7
+ static PLANE = "PLANE";
8
+ static SKETCH = "SKETCH";
9
+ static EDGE = "EDGE";
10
+ static LOOP = "LOOP";
11
+ static VERTEX = "VERTEX";
12
+ static ALL = "ALL";
13
+
14
+ // The set (or ALL) of types available in the current context
15
+ static allowedSelectionTypes = SelectionFilter.ALL;
16
+ static viewer = null;
17
+ static previouseAllowedSelectionTypes = null;
18
+ static _hovered = new Set(); // objects currently hover-highlighted
19
+ static hoverColor = '#fbff00'; // default hover tint
20
+
21
+ constructor() {
22
+ throw new Error("SelectionFilter is static and cannot be instantiated.");
23
+ }
24
+
25
+ static get TYPES() { return [this.SOLID, this.COMPONENT, this.FACE, this.PLANE, this.SKETCH, this.EDGE, this.LOOP, this.VERTEX, this.ALL]; }
26
+
27
+ // Convenience: return the list of selectable types for the dropdown (excludes ALL)
28
+ static getAvailableTypes() {
29
+ if (SelectionFilter.allowedSelectionTypes === SelectionFilter.ALL) {
30
+ return SelectionFilter.TYPES.filter(t => t !== SelectionFilter.ALL);
31
+ }
32
+ const arr = Array.from(SelectionFilter.allowedSelectionTypes || []);
33
+ return arr.filter(t => t && t !== SelectionFilter.ALL);
34
+ }
35
+
36
+ static getCurrentType() {
37
+ // Current type tracking has been removed; keep method for compatibility.
38
+ return null;
39
+ }
40
+
41
+ static setCurrentType(_type) {
42
+ // No-op: current type is no longer tracked.
43
+ void _type;
44
+ }
45
+
46
+ static SetSelectionTypes(types) {
47
+
48
+ this.viewer.endSplineMode();
49
+ if (types === SelectionFilter.ALL) {
50
+ SelectionFilter.allowedSelectionTypes = SelectionFilter.ALL;
51
+ SelectionFilter.triggerUI();
52
+ SelectionFilter.#logAllowedTypesChange(SelectionFilter.allowedSelectionTypes, 'SetSelectionTypes');
53
+ return;
54
+ }
55
+ const list = Array.isArray(types) ? types : [types];
56
+ const invalid = list.filter(t => !SelectionFilter.TYPES.includes(t) || t === SelectionFilter.ALL);
57
+ if (invalid.length) throw new Error(`Unknown selection type(s): ${invalid.join(", ")}`);
58
+ SelectionFilter.allowedSelectionTypes = new Set(list);
59
+ SelectionFilter.triggerUI();
60
+ SelectionFilter.#logAllowedTypesChange(SelectionFilter.allowedSelectionTypes, 'SetSelectionTypes');
61
+ }
62
+
63
+ static stashAllowedSelectionTypes() {
64
+ SelectionFilter.previouseAllowedSelectionTypes = SelectionFilter.allowedSelectionTypes;
65
+ }
66
+
67
+ static restoreAllowedSelectionTypes() {
68
+ if (SelectionFilter.previouseAllowedSelectionTypes !== null) {
69
+ SelectionFilter.allowedSelectionTypes = SelectionFilter.previouseAllowedSelectionTypes;
70
+ SelectionFilter.previouseAllowedSelectionTypes = null;
71
+ SelectionFilter.triggerUI();
72
+ SelectionFilter.#logAllowedTypesChange(SelectionFilter.allowedSelectionTypes, 'RestoreSelectionTypes');
73
+ }
74
+ }
75
+
76
+
77
+
78
+ static allowType(type) {
79
+ // Legacy support: expand available set; does not change currentType
80
+ if (type === SelectionFilter.ALL) { SelectionFilter.allowedSelectionTypes = SelectionFilter.ALL; SelectionFilter.triggerUI(); return; }
81
+ if (SelectionFilter.TYPES.includes(type)) {
82
+ if (SelectionFilter.allowedSelectionTypes === SelectionFilter.ALL) { SelectionFilter.triggerUI(); return; }
83
+ SelectionFilter.allowedSelectionTypes.add(type);
84
+ } else throw new Error(`Unknown selection type: ${type}`);
85
+ SelectionFilter.triggerUI();
86
+ SelectionFilter.#logAllowedTypesChange(SelectionFilter.allowedSelectionTypes, 'allowType');
87
+ }
88
+
89
+ static disallowType(type) {
90
+ // Legacy support: shrink available set; does not change currentType (may become invalid until next SetSelectionTypes)
91
+ if (SelectionFilter.allowedSelectionTypes === SelectionFilter.ALL) SelectionFilter.allowedSelectionTypes = new Set();
92
+ if (SelectionFilter.TYPES.includes(type)) SelectionFilter.allowedSelectionTypes.delete(type);
93
+ else throw new Error(`Unknown selection type: ${type}`);
94
+ SelectionFilter.triggerUI();
95
+ SelectionFilter.#logAllowedTypesChange(SelectionFilter.allowedSelectionTypes, 'disallowType');
96
+ }
97
+
98
+ static GetSelectionTypes() {
99
+ const v = SelectionFilter.allowedSelectionTypes;
100
+ return v === SelectionFilter.ALL ? SelectionFilter.ALL : Array.from(v);
101
+ }
102
+
103
+ // Check against the allowed set only (ignores currentType)
104
+ static matchesAllowedType(type) {
105
+ if (!type) return false;
106
+ if (SelectionFilter.allowedSelectionTypes === SelectionFilter.ALL) return true;
107
+ return SelectionFilter.allowedSelectionTypes?.has?.(type) || false;
108
+ }
109
+
110
+ static IsAllowed(type) {
111
+ if (!type) return false;
112
+ return SelectionFilter.matchesAllowedType(type);
113
+ }
114
+
115
+ static Reset() {
116
+ SelectionFilter.allowedSelectionTypes = SelectionFilter.ALL;
117
+ SelectionFilter.triggerUI();
118
+ SelectionFilter.#logAllowedTypesChange(SelectionFilter.allowedSelectionTypes, 'Reset');
119
+ }
120
+
121
+ static #getBaseMaterial(obj) {
122
+ if (!obj) return null;
123
+ const ud = obj.userData || {};
124
+ if (ud.__baseMaterial) return ud.__baseMaterial;
125
+ if (obj.type === SelectionFilter.FACE) return CADmaterials.FACE?.BASE ?? CADmaterials.FACE ?? obj.material;
126
+ if (obj.type === SelectionFilter.PLANE) return CADmaterials.PLANE?.BASE ?? CADmaterials.FACE?.BASE ?? obj.material;
127
+ if (obj.type === SelectionFilter.EDGE) return CADmaterials.EDGE?.BASE ?? CADmaterials.EDGE ?? obj.material;
128
+ if (obj.type === SelectionFilter.SOLID || obj.type === SelectionFilter.COMPONENT) return obj.material;
129
+ return obj.material;
130
+ }
131
+
132
+ // ---------------- Hover Highlighting ----------------
133
+ static getHoverColor() { return SelectionFilter.hoverColor; }
134
+ static setHoverColor(hex) {
135
+ if (!hex) return;
136
+ try { SelectionFilter.hoverColor = String(hex); } catch (_) { }
137
+ // Update current hovered objects live
138
+ for (const o of Array.from(SelectionFilter._hovered)) {
139
+ if (o && o.material && o.material.color && typeof o.material.color.set === 'function') {
140
+ try { o.material.color.set(SelectionFilter.hoverColor); } catch (_) { }
141
+ }
142
+ }
143
+ }
144
+
145
+ static setHoverObject(obj, options = {}) {
146
+ const { ignoreFilter = false } = options;
147
+ // Clear existing hover first
148
+ SelectionFilter.clearHover();
149
+ if (!obj) return;
150
+ // Highlight depending on type
151
+ SelectionFilter.#applyHover(obj, { ignoreFilter });
152
+ }
153
+
154
+ static setHoverByName(scene, name) {
155
+ if (!scene || !name) { SelectionFilter.clearHover(); return; }
156
+ const obj = scene.getObjectByName(name);
157
+ if (!obj) { SelectionFilter.clearHover(); return; }
158
+ SelectionFilter.setHoverObject(obj);
159
+ }
160
+
161
+ static clearHover() {
162
+ if (!SelectionFilter._hovered || SelectionFilter._hovered.size === 0) return;
163
+ for (const o of Array.from(SelectionFilter._hovered)) {
164
+ SelectionFilter.#restoreHover(o);
165
+ }
166
+ SelectionFilter._hovered.clear();
167
+ }
168
+
169
+ static #applyHover(obj, options = {}) {
170
+ const { ignoreFilter = false } = options;
171
+ if (!obj) return;
172
+ // Respect selection filter: skip if disallowed
173
+ const allowed = ignoreFilter
174
+ || SelectionFilter.IsAllowed(obj.type)
175
+ || SelectionFilter.matchesAllowedType(obj.type);
176
+ if (!allowed) return;
177
+
178
+ // Only ever highlight one object: the exact object provided, if it has a color
179
+ const target = obj;
180
+ if (!target) return;
181
+
182
+ const applyToOne = (t) => {
183
+ if (!t) return;
184
+ if (!t.userData) t.userData = {};
185
+ const origMat = t.material;
186
+ if (!origMat) return;
187
+ if (t.userData.__hoverMatApplied) { SelectionFilter._hovered.add(t); return; }
188
+ let clone;
189
+ try { clone = typeof origMat.clone === 'function' ? origMat.clone() : origMat; } catch { clone = origMat; }
190
+ try { if (clone && clone.color && typeof clone.color.set === 'function') clone.color.set(SelectionFilter.hoverColor); } catch { }
191
+ try {
192
+ t.userData.__hoverOrigMat = origMat;
193
+ t.userData.__hoverMatApplied = true;
194
+ if (clone !== origMat) t.material = clone;
195
+ t.userData.__hoverMat = clone;
196
+ } catch { }
197
+ SelectionFilter._hovered.add(t);
198
+ };
199
+
200
+ if (target.type === SelectionFilter.SOLID || target.type === SelectionFilter.COMPONENT) {
201
+ // Highlight all immediate child faces/edges for SOLID or COMPONENT children
202
+ if (Array.isArray(target.children)) {
203
+ for (const ch of target.children) {
204
+ if (!ch) continue;
205
+ if (ch.type === SelectionFilter.SOLID || ch.type === SelectionFilter.COMPONENT) {
206
+ if (Array.isArray(ch.children)) {
207
+ for (const nested of ch.children) {
208
+ if (nested && (nested.type === SelectionFilter.FACE || nested.type === SelectionFilter.EDGE)) applyToOne(nested);
209
+ }
210
+ }
211
+ } else if (ch.type === SelectionFilter.FACE || ch.type === SelectionFilter.EDGE) {
212
+ applyToOne(ch);
213
+ }
214
+ }
215
+ }
216
+ // Track the solid as a logical hovered root to clear later
217
+ SelectionFilter._hovered.add(target);
218
+ return;
219
+ }
220
+
221
+ if (target.type === SelectionFilter.VERTEX) {
222
+ // Apply to the vertex object and any drawable children (e.g., Points)
223
+ applyToOne(target);
224
+ if (Array.isArray(target.children)) {
225
+ for (const ch of target.children) {
226
+ applyToOne(ch);
227
+ }
228
+ }
229
+ return;
230
+ }
231
+
232
+ applyToOne(target);
233
+ }
234
+
235
+ static #restoreHover(obj) {
236
+ if (!obj) return;
237
+ const restoreOne = (t) => {
238
+ if (!t) return;
239
+ const ud = t.userData || {};
240
+ if (!ud.__hoverMatApplied) return;
241
+ const cloneWithColor = (mat, colorHex) => {
242
+ if (!mat) return mat;
243
+ let c = mat;
244
+ try {
245
+ c = typeof mat.clone === 'function' ? mat.clone() : mat;
246
+ if (c && c.color && typeof c.color.set === 'function' && colorHex) c.color.set(colorHex);
247
+ } catch { c = mat; }
248
+ return c;
249
+ };
250
+ const applySelectionMaterial = () => {
251
+ if (t.type === SelectionFilter.FACE) return CADmaterials.FACE?.SELECTED ?? CADmaterials.FACE ?? ud.__hoverOrigMat ?? t.material;
252
+ if (t.type === SelectionFilter.PLANE) return CADmaterials.PLANE?.SELECTED ?? CADmaterials.FACE?.SELECTED ?? ud.__hoverOrigMat ?? t.material;
253
+ if (t.type === SelectionFilter.EDGE) {
254
+ const base = ud.__hoverOrigMat ?? t.material;
255
+ const selColor = CADmaterials.EDGE?.SELECTED?.color || CADmaterials.EDGE?.SELECTED?.color?.getHexString?.();
256
+ return cloneWithColor(base, selColor || '#ff00ff');
257
+ }
258
+ if (t.type === SelectionFilter.SOLID || t.type === SelectionFilter.COMPONENT) return CADmaterials.SOLID?.SELECTED ?? ud.__hoverOrigMat ?? t.material;
259
+ return ud.__hoverOrigMat ?? t.material;
260
+ };
261
+ const applyDeselectedMaterial = () => {
262
+ if (t.type === SelectionFilter.FACE) return ud.__hoverOrigMat ?? SelectionFilter.#getBaseMaterial(t) ?? t.material;
263
+ if (t.type === SelectionFilter.PLANE) return ud.__hoverOrigMat ?? SelectionFilter.#getBaseMaterial(t) ?? t.material;
264
+ if (t.type === SelectionFilter.EDGE) return ud.__hoverOrigMat ?? SelectionFilter.#getBaseMaterial(t) ?? t.material;
265
+ if (t.type === SelectionFilter.SOLID || t.type === SelectionFilter.COMPONENT) return ud.__hoverOrigMat ?? t.material;
266
+ return ud.__hoverOrigMat ?? t.material;
267
+ };
268
+ try {
269
+ if (t.selected) {
270
+ const selMat = applySelectionMaterial();
271
+ if (selMat) t.material = selMat;
272
+ } else {
273
+ const baseMat = applyDeselectedMaterial();
274
+ if (baseMat) t.material = baseMat;
275
+ }
276
+ if (ud.__hoverMat && ud.__hoverMat !== ud.__hoverOrigMat && typeof ud.__hoverMat.dispose === 'function') ud.__hoverMat.dispose();
277
+ } catch { }
278
+ try { delete t.userData.__hoverMatApplied; } catch { }
279
+ try { delete t.userData.__hoverOrigMat; } catch { }
280
+ try { delete t.userData.__hoverMat; } catch { }
281
+ };
282
+
283
+ if (obj.type === SelectionFilter.SOLID || obj.type === SelectionFilter.COMPONENT) {
284
+ if (Array.isArray(obj.children)) {
285
+ for (const ch of obj.children) restoreOne(ch);
286
+ }
287
+ }
288
+ if (obj.type === SelectionFilter.VERTEX) {
289
+ if (Array.isArray(obj.children)) {
290
+ for (const ch of obj.children) restoreOne(ch);
291
+ }
292
+ }
293
+ restoreOne(obj);
294
+ }
295
+
296
+ static #isInputUsable(el) {
297
+ // Use the closest visible wrapper as the visibility anchor; hidden inputs themselves render display:none
298
+ const anchor = (el && typeof el.closest === 'function')
299
+ ? (el.closest('.ref-single-wrap, .ref-multi-wrap') || el)
300
+ : el;
301
+ if (!anchor || !anchor.isConnected) return false;
302
+ const seen = new Set();
303
+ let node = anchor;
304
+ while (node && !seen.has(node)) {
305
+ seen.add(node);
306
+ if (node.hidden === true) return false;
307
+ try {
308
+ const style = window.getComputedStyle(node);
309
+ if (style && (style.display === 'none' || style.visibility === 'hidden')) return false;
310
+ } catch (_) { /* ignore */ }
311
+ const root = (typeof node.getRootNode === 'function') ? node.getRootNode() : null;
312
+ if (root && root.host && root !== node) {
313
+ node = root.host;
314
+ continue;
315
+ }
316
+ node = node.parentElement;
317
+ }
318
+ return true;
319
+ }
320
+
321
+ static toggleSelection(objectToToggleSelectionOn) {
322
+ // get the type of the object
323
+ const type = objectToToggleSelectionOn.type;
324
+ if (!type) throw new Error("Object to toggle selection on must have a type.");
325
+
326
+ // Check if a reference selection is active
327
+ try {
328
+ let activeRefInput = document.querySelector('[active-reference-selection="true"],[active-reference-selection=true]');
329
+ if (!activeRefInput) {
330
+ try { activeRefInput = window.__BREP_activeRefInput || null; } catch (_) { /* ignore */ }
331
+ }
332
+ if (activeRefInput) {
333
+ const usable = SelectionFilter.#isInputUsable(activeRefInput);
334
+ if (!usable) {
335
+ try { activeRefInput.removeAttribute('active-reference-selection'); } catch (_) { }
336
+ try { activeRefInput.style.filter = 'none'; } catch (_) { }
337
+ try { if (window.__BREP_activeRefInput === activeRefInput) window.__BREP_activeRefInput = null; } catch (_) { }
338
+ SelectionFilter.restoreAllowedSelectionTypes();
339
+ return false;
340
+ }
341
+
342
+ const dataset = activeRefInput.dataset || {};
343
+ const isMultiRef = dataset.multiple === 'true';
344
+ const maxSelections = Number(dataset.maxSelections);
345
+ const hasMax = Number.isFinite(maxSelections) && maxSelections > 0;
346
+ if (isMultiRef) {
347
+ let currentCount = 0;
348
+ try {
349
+ if (typeof activeRefInput.__getSelectionList === 'function') {
350
+ const list = activeRefInput.__getSelectionList();
351
+ if (Array.isArray(list)) currentCount = list.length;
352
+ } else if (dataset.selectedCount !== undefined) {
353
+ const parsed = Number(dataset.selectedCount);
354
+ if (Number.isFinite(parsed)) currentCount = parsed;
355
+ }
356
+ } catch (_) { /* ignore */ }
357
+ if (hasMax && currentCount >= maxSelections) {
358
+ try {
359
+ const wrap = activeRefInput.closest('.ref-single-wrap, .ref-multi-wrap');
360
+ if (wrap) {
361
+ wrap.classList.add('ref-limit-reached');
362
+ setTimeout(() => {
363
+ try { wrap.classList.remove('ref-limit-reached'); } catch (_) { }
364
+ }, 480);
365
+ }
366
+ } catch (_) { }
367
+ return true;
368
+ }
369
+ }
370
+ const allowed = SelectionFilter.allowedSelectionTypes;
371
+ const allowAll = allowed === SelectionFilter.ALL;
372
+ const priorityOrder = [
373
+ SelectionFilter.VERTEX,
374
+ SelectionFilter.EDGE,
375
+ SelectionFilter.FACE,
376
+ SelectionFilter.PLANE,
377
+ SelectionFilter.SOLID,
378
+ SelectionFilter.COMPONENT,
379
+ ];
380
+ const allowedHas = (t) => !!(allowed && typeof allowed.has === 'function' && allowed.has(t));
381
+ const allowedPriority = allowAll ? priorityOrder : priorityOrder.filter(t => allowedHas(t));
382
+
383
+ // Helper: find first descendant matching a type
384
+ const findDescendantOfType = (root, desired) => {
385
+ if (!root || !desired) return null;
386
+ let found = null;
387
+ try {
388
+ root.traverse?.((ch) => {
389
+ if (!found && ch && ch.type === desired) found = ch;
390
+ });
391
+ } catch (_) { /* ignore */ }
392
+ return found;
393
+ };
394
+
395
+ const findAncestorOfType = (obj, desired) => {
396
+ let cur = obj;
397
+ while (cur && cur.parent) {
398
+ if (cur.type === desired) return cur;
399
+ cur = cur.parent;
400
+ }
401
+ return null;
402
+ };
403
+ const pickByTypeList = (typeList) => {
404
+ if (!Array.isArray(typeList)) return null;
405
+ for (const desired of typeList) {
406
+ if (!desired) continue;
407
+ if (objectToToggleSelectionOn?.type === desired) return objectToToggleSelectionOn;
408
+ let picked = findDescendantOfType(objectToToggleSelectionOn, desired);
409
+ if (!picked) picked = findAncestorOfType(objectToToggleSelectionOn, desired);
410
+ if (picked) return picked;
411
+ }
412
+ return null;
413
+ };
414
+
415
+ let targetObj = null;
416
+ // Prefer the exact object the user clicked if it is allowed.
417
+ if (allowAll || allowedHas(objectToToggleSelectionOn?.type)) {
418
+ targetObj = objectToToggleSelectionOn;
419
+ }
420
+ if (!targetObj) {
421
+ targetObj = pickByTypeList(allowedPriority);
422
+ }
423
+ if (!targetObj && !allowAll && allowed && typeof allowed[Symbol.iterator] === 'function') {
424
+ targetObj = pickByTypeList(Array.from(allowed));
425
+ }
426
+ if (!targetObj && allowAll) {
427
+ targetObj = objectToToggleSelectionOn;
428
+ }
429
+ if (!targetObj) return false;
430
+
431
+ // Update the reference input with the chosen object
432
+ const objType = targetObj.type;
433
+ const objectName = targetObj.name || `${objType}(${targetObj.position?.x || 0},${targetObj.position?.y || 0},${targetObj.position?.z || 0})`;
434
+
435
+ const snapshotSelections = (inputEl) => {
436
+ const data = inputEl?.dataset || {};
437
+ let values = null;
438
+ if (data.selectedValues) {
439
+ try {
440
+ const parsed = JSON.parse(data.selectedValues);
441
+ if (Array.isArray(parsed)) values = parsed;
442
+ } catch (_) { /* ignore */ }
443
+ }
444
+ if (!Array.isArray(values) && typeof inputEl?.__getSelectionList === 'function') {
445
+ try {
446
+ const list = inputEl.__getSelectionList();
447
+ if (Array.isArray(list)) values = list.slice();
448
+ } catch (_) { /* ignore */ }
449
+ }
450
+ let count = 0;
451
+ if (Array.isArray(values)) {
452
+ count = values.length;
453
+ } else if (data.selectedCount !== undefined) {
454
+ const parsed = Number(data.selectedCount);
455
+ if (Number.isFinite(parsed) && parsed >= 0) count = parsed;
456
+ }
457
+ return count;
458
+ };
459
+
460
+ activeRefInput.value = objectName;
461
+ activeRefInput.dispatchEvent(new Event('change'));
462
+ const afterSelectionCount = snapshotSelections(activeRefInput);
463
+
464
+ const didReachLimit = isMultiRef && hasMax && afterSelectionCount >= maxSelections;
465
+ const keepActive = isMultiRef && !didReachLimit;
466
+
467
+ if (!keepActive) {
468
+ // Clean up the reference selection state
469
+ activeRefInput.removeAttribute('active-reference-selection');
470
+ activeRefInput.style.filter = 'none';
471
+ try {
472
+ const wrap = activeRefInput.closest('.ref-single-wrap, .ref-multi-wrap');
473
+ if (wrap) wrap.classList.remove('ref-active');
474
+ } catch (_) { }
475
+ // Restore selection filter
476
+ SelectionFilter.restoreAllowedSelectionTypes();
477
+ try { if (window.__BREP_activeRefInput === activeRefInput) window.__BREP_activeRefInput = null; } catch (_) { }
478
+ } else {
479
+ activeRefInput.setAttribute('active-reference-selection', 'true');
480
+ activeRefInput.style.filter = 'invert(1)';
481
+ try {
482
+ const wrap = activeRefInput.closest('.ref-single-wrap, .ref-multi-wrap');
483
+ if (wrap) wrap.classList.add('ref-active');
484
+ } catch (_) { }
485
+ try { window.__BREP_activeRefInput = activeRefInput; } catch (_) { }
486
+ }
487
+ return true; // handled as a reference selection
488
+ }
489
+ } catch (error) {
490
+ console.warn("Error handling reference selection:", error);
491
+ }
492
+
493
+ let parentSelectedAction = false;
494
+ // check if the object is selectable and if it is toggle the .selected atribute on the object.
495
+ // Allow toggling off even if type is currently disallowed; only block new selections
496
+ if (SelectionFilter.IsAllowed(type) || objectToToggleSelectionOn.selected === true) {
497
+ objectToToggleSelectionOn.selected = !objectToToggleSelectionOn.selected;
498
+ // change the material on the object to indicate it is selected or not.
499
+ if (objectToToggleSelectionOn.selected) {
500
+ if (objectToToggleSelectionOn.type === SelectionFilter.FACE) {
501
+ objectToToggleSelectionOn.material = CADmaterials.FACE?.SELECTED ?? CADmaterials.FACE;
502
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.PLANE) {
503
+ objectToToggleSelectionOn.material = CADmaterials.PLANE?.SELECTED ?? CADmaterials.FACE?.SELECTED ?? objectToToggleSelectionOn.material;
504
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.EDGE) {
505
+ objectToToggleSelectionOn.material = CADmaterials.EDGE?.SELECTED ?? CADmaterials.EDGE;
506
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.VERTEX) {
507
+ // Vertex visuals are handled by its selected accessor (point + sphere)
508
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.SOLID || objectToToggleSelectionOn.type === SelectionFilter.COMPONENT) {
509
+ parentSelectedAction = true;
510
+ objectToToggleSelectionOn.children.forEach(child => {
511
+ // apply selected material based on object type for faces and edges
512
+ if (child.type === SelectionFilter.FACE) child.material = CADmaterials.FACE?.SELECTED ?? CADmaterials.FACE;
513
+ if (child.type === SelectionFilter.PLANE) child.material = CADmaterials.PLANE?.SELECTED ?? CADmaterials.FACE?.SELECTED ?? child.material;
514
+ if (child.type === SelectionFilter.EDGE) child.material = CADmaterials.EDGE?.SELECTED ?? CADmaterials.EDGE;
515
+ });
516
+ }
517
+
518
+ } else {
519
+ if (objectToToggleSelectionOn.type === SelectionFilter.FACE) {
520
+ objectToToggleSelectionOn.material = SelectionFilter.#getBaseMaterial(objectToToggleSelectionOn) ?? objectToToggleSelectionOn.material;
521
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.PLANE) {
522
+ objectToToggleSelectionOn.material = SelectionFilter.#getBaseMaterial(objectToToggleSelectionOn) ?? objectToToggleSelectionOn.material;
523
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.EDGE) {
524
+ objectToToggleSelectionOn.material = SelectionFilter.#getBaseMaterial(objectToToggleSelectionOn) ?? objectToToggleSelectionOn.material;
525
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.VERTEX) {
526
+ // Vertex accessor handles its own visual reset
527
+ } else if (objectToToggleSelectionOn.type === SelectionFilter.SOLID || objectToToggleSelectionOn.type === SelectionFilter.COMPONENT) {
528
+ parentSelectedAction = true;
529
+ objectToToggleSelectionOn.children.forEach(child => {
530
+ // apply selected material based on object type for faces and edges
531
+ if (child.type === SelectionFilter.FACE) child.material = child.selected ? CADmaterials.FACE?.SELECTED ?? CADmaterials.FACE : (SelectionFilter.#getBaseMaterial(child) ?? child.material);
532
+ if (child.type === SelectionFilter.PLANE) child.material = child.selected ? (CADmaterials.PLANE?.SELECTED ?? CADmaterials.FACE?.SELECTED ?? child.material) : (SelectionFilter.#getBaseMaterial(child) ?? child.material);
533
+ if (child.type === SelectionFilter.EDGE) child.material = child.selected ? CADmaterials.EDGE?.SELECTED ?? CADmaterials.EDGE : (SelectionFilter.#getBaseMaterial(child) ?? child.material);
534
+ });
535
+ }
536
+ }
537
+ SelectionFilter._emitSelectionChanged();
538
+ }
539
+
540
+ return parentSelectedAction;
541
+ }
542
+
543
+ static unselectAll(scene) {
544
+ // itterate over all children and nested children of the scene and set the .selected atribute to false.
545
+ scene.traverse((child) => {
546
+ child.selected = false;
547
+ // reset material to base
548
+ if (child.type === SelectionFilter.FACE) {
549
+ child.material = SelectionFilter.#getBaseMaterial(child) ?? child.material;
550
+ } else if (child.type === SelectionFilter.PLANE) {
551
+ child.material = SelectionFilter.#getBaseMaterial(child) ?? child.material;
552
+ } else if (child.type === SelectionFilter.EDGE) {
553
+ child.material = SelectionFilter.#getBaseMaterial(child) ?? child.material;
554
+ }
555
+
556
+ });
557
+ SelectionFilter._emitSelectionChanged();
558
+ }
559
+
560
+ static selectItem(scene, itemName) {
561
+ scene.traverse((child) => {
562
+ if (child instanceof THREE.Mesh && child.name === itemName) {
563
+ child.selected = true;
564
+ // change material to selected
565
+ if (child.type === SelectionFilter.FACE) {
566
+ child.material = CADmaterials.FACE?.SELECTED ?? CADmaterials.FACE;
567
+ } else if (child.type === SelectionFilter.PLANE) {
568
+ child.material = CADmaterials.PLANE?.SELECTED ?? CADmaterials.FACE?.SELECTED ?? child.material;
569
+ } else if (child.type === SelectionFilter.EDGE) {
570
+ child.material = CADmaterials.EDGE?.SELECTED ?? CADmaterials.EDGE;
571
+ } else if (child.type === SelectionFilter.SOLID || child.type === SelectionFilter.COMPONENT) {
572
+ child.material = CADmaterials.SOLID?.SELECTED ?? CADmaterials.SOLID;
573
+ }
574
+ }
575
+ });
576
+ SelectionFilter._emitSelectionChanged();
577
+ }
578
+
579
+ static deselectItem(scene, itemName) {
580
+ // Traverse scene and deselect a single item by name, updating materials appropriately
581
+ scene.traverse((child) => {
582
+ if (child.name === itemName) {
583
+ child.selected = false;
584
+ if (child.type === SelectionFilter.FACE) {
585
+ child.material = SelectionFilter.#getBaseMaterial(child) ?? child.material;
586
+ } else if (child.type === SelectionFilter.PLANE) {
587
+ child.material = SelectionFilter.#getBaseMaterial(child) ?? child.material;
588
+ } else if (child.type === SelectionFilter.EDGE) {
589
+ child.material = SelectionFilter.#getBaseMaterial(child) ?? child.material;
590
+ } else if (child.type === SelectionFilter.SOLID || child.type === SelectionFilter.COMPONENT) {
591
+ // For solids, keep children materials consistent with their own selected flags
592
+ child.children.forEach(grandchild => {
593
+ if (grandchild.type === SelectionFilter.FACE) {
594
+ grandchild.material = grandchild.selected ? (CADmaterials.FACE?.SELECTED ?? CADmaterials.FACE) : (SelectionFilter.#getBaseMaterial(grandchild) ?? grandchild.material);
595
+ }
596
+ if (grandchild.type === SelectionFilter.PLANE) {
597
+ grandchild.material = grandchild.selected ? (CADmaterials.PLANE?.SELECTED ?? CADmaterials.FACE?.SELECTED ?? grandchild.material) : (SelectionFilter.#getBaseMaterial(grandchild) ?? grandchild.material);
598
+ }
599
+ if (grandchild.type === SelectionFilter.EDGE) {
600
+ grandchild.material = grandchild.selected ? (CADmaterials.EDGE?.SELECTED ?? CADmaterials.EDGE) : (SelectionFilter.#getBaseMaterial(grandchild) ?? grandchild.material);
601
+ }
602
+ });
603
+ }
604
+ }
605
+ });
606
+ SelectionFilter._emitSelectionChanged();
607
+ }
608
+
609
+ static set uiCallback(callback) { SelectionFilter._uiCallback = callback; }
610
+ static triggerUI() { if (SelectionFilter._uiCallback) SelectionFilter._uiCallback(); }
611
+
612
+ // Emit a global event so UI can react without polling
613
+ static _emitSelectionChanged() {
614
+ try {
615
+ const ev = new CustomEvent('selection-changed');
616
+ window.dispatchEvent(ev);
617
+ } catch (_) { /* noop */ }
618
+ }
619
+
620
+ static #logAllowedTypesChange(next, reason = '') {
621
+ try {
622
+ const desc = next === SelectionFilter.ALL
623
+ ? 'ALL'
624
+ : JSON.stringify(Array.from(next || []));
625
+ const prefix = reason ? `[SelectionFilter:${reason}]` : '[SelectionFilter]';
626
+ console.log(`${prefix} Allowed types -> ${desc}`);
627
+ } catch { /* ignore logging errors */ }
628
+ }
629
+ }