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