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,359 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title>Solid Methods Reference - BREP</title>
7
+ <style>
8
+ :root{
9
+ --bg:#0b0f14; --panel:#0f141b; --text:#d7dde6; --muted:#9aa7b2;
10
+ --border:#1b2430; --accent:#5cc8ff; --chip:#121823;
11
+ }
12
+ *{box-sizing:border-box}
13
+ html,body{margin:0;background:var(--bg);color:var(--text);font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono','Courier New',monospace}
14
+ main{max-width:1100px;margin:0 auto;padding:28px}
15
+ h1{margin:0 0 18px;font-size:22px;color:var(--accent);font-weight:700}
16
+ .summary{color:var(--muted);margin-bottom:22px}
17
+ .card{background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:18px;margin:0 0 18px}
18
+ .readme{padding:0}
19
+ .readme .header{padding:16px 18px;border-bottom:1px solid var(--border)}
20
+ .readme .content{padding:18px}
21
+ .doc-card{padding:18px}
22
+ .doc-nav{margin:0 0 18px;display:flex;gap:12px;flex-wrap:wrap;align-items:center;color:var(--muted)}
23
+ .doc-nav-links{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
24
+ .doc-nav a{color:var(--accent);font-weight:600}
25
+ .doc-list{list-style:none;margin:18px 0;padding:0}
26
+ .doc-list li{margin:6px 0}
27
+ .doc-list a{color:var(--accent)}
28
+ .nav-search{margin-left:auto;position:relative;display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end;min-width:240px;max-width:520px}
29
+ .search-title{font-weight:700;font-size:14px;margin-bottom:4px}
30
+ .search-hint{color:var(--muted);font-size:12px;margin:0}
31
+ .search-input-row{display:flex;gap:8px;align-items:center;width:100%}
32
+ .search-input{flex:1;border:1px solid var(--border);border-radius:10px;background:var(--chip);color:var(--text);padding:10px 12px}
33
+ .search-input:focus{outline:1px solid var(--accent);box-shadow:0 0 0 3px rgba(92,200,255,0.15)}
34
+ .search-clear{border:1px solid var(--border);background:var(--panel);color:var(--muted);border-radius:10px;padding:9px 12px;cursor:pointer;font-weight:600}
35
+ .search-clear:hover{border-color:var(--accent);color:var(--accent)}
36
+ .search-status{color:var(--muted);font-size:12px;margin-top:4px;width:100%;text-align:right}
37
+ .search-results{position:absolute;top:100%;right:0;margin-top:10px;border:1px solid var(--border);border-radius:12px;background:var(--panel);max-height:360px;overflow:auto;min-width:320px;max-width:520px;box-shadow:0 12px 30px rgba(0,0,0,0.35);z-index:25}
38
+ .search-results ul{list-style:none;margin:0;padding:0}
39
+ .search-item{padding:10px 12px;border-bottom:1px solid var(--border)}
40
+ .search-item:last-child{border-bottom:none}
41
+ .search-item a{display:block;color:var(--accent);font-weight:600}
42
+ .search-snippet{color:var(--muted);font-size:13px;margin-top:4px}
43
+ .search-results mark{background:rgba(92,200,255,0.2);color:var(--text);border-radius:4px;padding:0 2px}
44
+ .prose h1{font-size:24px;margin:0 0 12px}
45
+ .prose h2{font-size:18px;margin:18px 0 8px}
46
+ .prose h3{font-size:16px;margin:14px 0 6px}
47
+ .prose p{margin:0 0 10px}
48
+ .prose ul,.prose ol{margin:0 0 10px 18px}
49
+ .prose li{margin:4px 0}
50
+ .prose code{background:#0d1520;border:1px solid var(--border);padding:1px 5px;border-radius:6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono','Courier New',monospace;font-size:12px}
51
+ .prose pre{background:#0d1520;border:1px solid var(--border);padding:12px;border-radius:12px;overflow:auto}
52
+ .prose a{color:var(--accent)}
53
+ .prose img{max-width:100%;height:auto;}
54
+ .prose table{border-collapse:collapse;width:100%;margin:16px 0;background:var(--panel);border:1px solid var(--border);border-radius:8px;overflow:hidden}
55
+ .prose th,.prose td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--border)}
56
+ .prose th{background:var(--chip);color:var(--text);font-weight:600;font-size:13px}
57
+ .prose tr:last-child td{border-bottom:none}
58
+ .prose tbody tr:hover{background:rgba(92,200,255,0.05)}
59
+ .license{
60
+ background:var(--panel);border:1px solid var(--border);border-radius:14px;
61
+ padding:16px 16px 8px;margin:0 0 18px;
62
+ }
63
+ .license > h2{margin:0 0 10px;font-size:16px;font-weight:700}
64
+ .pkg{
65
+ border-top:1px solid var(--border);padding:10px 0;
66
+ display:grid;grid-template-columns:1fr auto;gap:10px;align-items:center;
67
+ }
68
+ .pkg:first-of-type{border-top:none}
69
+ .pkg .meta{display:flex;gap:10px;flex-wrap:wrap}
70
+ .pkg .name{font-weight:600}
71
+ .pkg .desc{color:var(--muted);margin-top:2px}
72
+ a{color:var(--accent);text-decoration:none} a:hover{text-decoration:underline}
73
+ .chip{background:var(--chip);border:1px solid var(--border);border-radius:999px;padding:2px 8px;font-size:12px;color:var(--muted)}
74
+ .footer{margin-top:26px;color:var(--muted);font-size:12px}
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <main>
79
+ <nav class="doc-nav">
80
+ <div class="doc-nav-links">
81
+ <a href="index.html">Help Home</a><span>&middot;</span><a href="/help/table-of-contents.html">Table of Contents</a><span>&middot;</span><a href="https://github.com/mmiscool/BREP" target="_blank" rel="noopener noreferrer">GitHub</a>
82
+ </div>
83
+ <div class="nav-search">
84
+ <div class="search-input-row">
85
+ <input type="search" id="doc-search" class="search-input" placeholder="Search docs... Type at least 2 characters to search" autocomplete="off" spellcheck="false" />
86
+ <button type="button" class="search-clear" id="doc-search-clear">Clear</button>
87
+ </div>
88
+ <div class="search-status" id="doc-search-status"></div>
89
+ <div class="search-results" id="doc-search-results" hidden>
90
+ <ul id="doc-search-list"></ul>
91
+ </div>
92
+ </div>
93
+ </nav>
94
+ <section class="card doc-card">
95
+
96
+ <div class="prose">
97
+ <h1>Solid Methods Reference</h1><p><code>Solid</code> lives in <code>src/BREP/BetterSolid.js</code> and extends <code>THREE.Group</code>. Examples below assume:</p><p><pre><code>js
98
+ import { Solid } from &#39;../src/BREP/BetterSolid.js&#39;;
99
+ const solid = new Solid();</code></pre></p><h2>Lifecycle</h2><h3>constructor()</h3><p>Initializes empty authoring buffers, face/edge metadata maps, and flags the manifold cache as dirty. <pre><code>js
100
+ const s = new Solid();</code></pre></p><h3>clone()</h3><p>Creates a lightweight copy of geometry, face/edge metadata, and aux edges (no THREE children or GPU resources). <pre><code>js
101
+ const copy = solid.clone();</code></pre></p><h3>free()</h3><p>Disposes the cached <code>Manifold</code> instance to release wasm memory; the Solid remains usable and will rebuild on demand. <pre><code>js
102
+ solid.free();</code></pre></p><h3>faces (getter)</h3><p>Ensures <code>visualize()</code> has run, then returns <code>FACE</code> children currently attached to the group. <pre><code>js
103
+ const faceMeshes = solid.faces;</code></pre></p><h2>Authoring</h2><h3>addTriangle(faceName, v1, v2, v3)</h3><p>Appends a CCW triangle labeled with <code>faceName</code>; vertices are uniqued by exact coordinates. <pre><code>js
104
+ solid.addTriangle(&#39;TOP&#39;, [0, 0, 0], [1, 0, 0], [0, 1, 0]);</code></pre></p><h3>_key([x, y, z])</h3><p>Internal: builds the exact string key used for vertex deduplication. <pre><code>js
105
+ const key = solid._key([0, 0, 0]); // &quot;0,0,0&quot;</code></pre></p><h3>_getPointIndex(point)</h3><p>Internal: returns the existing vertex index or appends the point to the authoring buffer. <pre><code>js
106
+ const idx = solid._getPointIndex([1, 2, 3]);</code></pre></p><h3>_getOrCreateID(faceName)</h3><p>Internal: maps a face name to a globally unique Manifold ID, creating one if needed. <pre><code>js
107
+ const faceId = solid._getOrCreateID(&#39;SIDE&#39;);</code></pre></p><h3>addAuxEdge(name, points, options)</h3><p>Stores a helper polyline (e.g., centerline) for visualization alongside the solid. <pre><code>js
108
+ solid.addAuxEdge(&#39;CENTER&#39;, [[0, 0, 0], [0, 0, 5]], {
109
+ closedLoop: false, // render as loop when true
110
+ polylineWorld: false, // points already in world space?
111
+ materialKey: &#39;OVERLAY&#39; // visualization material tag
112
+ });</code></pre></p><h3>addCenterline(a, b, name?, options?)</h3><p>Convenience wrapper that records a two‑point aux edge. <pre><code>js
113
+ solid.addCenterline([0, 0, 0], [0, 0, 10], &#39;AXIS&#39;, {
114
+ closedLoop: false,
115
+ polylineWorld: false,
116
+ materialKey: &#39;OVERLAY&#39;
117
+ });</code></pre></p><h2>Metadata</h2><h3>setFaceMetadata(faceName, metadata)</h3><p>Attaches arbitrary metadata to a face label (merged if it already exists). <pre><code>js
118
+ solid.setFaceMetadata(&#39;CYL_SIDE&#39;, { radius: 5, axis: [0, 0, 1] });</code></pre></p><h3>getFaceMetadata(faceName)</h3><p>Reads face metadata; returns <code>{}</code> when unset. <pre><code>js
119
+ const data = solid.getFaceMetadata(&#39;CYL_SIDE&#39;);</code></pre></p><h3>getFaceNames()</h3><p>Lists all face labels present on the solid. <pre><code>js
120
+ const names = solid.getFaceNames();</code></pre></p><h3>setEdgeMetadata(edgeName, metadata) / getEdgeMetadata(edgeName)</h3><p>Stores or reads metadata for boundary edges (used by PMI and downstream tooling). <pre><code>js
121
+ solid.setEdgeMetadata(&#39;EDGE_A&#39;, { tag: &#39;reference&#39; });
122
+ const edgeInfo = solid.getEdgeMetadata(&#39;EDGE_A&#39;);</code></pre></p><h3>_combineFaceMetadata(other)</h3><p>Internal: merges face metadata maps across solids (used during booleans). <pre><code>js
123
+ const combined = solid._combineFaceMetadata(otherSolid);</code></pre></p><h2>Transforms and offsets</h2><h3>bakeTransform(matrix)</h3><p>Applies a <code>THREE.Matrix4</code> to authored vertices and aux edges, rebuilding the vertex index map. <pre><code>js
124
+ const m = new THREE.Matrix4().makeTranslation(0, 0, 10);
125
+ solid.bakeTransform(m);</code></pre></p><h3>bakeTRS(trs)</h3><p>Composes and bakes a transform from <code>{ t, rDeg, s }</code> using <code>composeTrsMatrixDeg</code>. <pre><code>js
126
+ solid.bakeTRS({ t: [0, 0, 10], rDeg: [0, 45, 0], s: [1, 1, 1] });</code></pre></p><h3>offsetFace(faceName, distance)</h3><p>Moves all vertices of a labeled face along its average normal by <code>distance</code>. <pre><code>js
127
+ solid.offsetFace(&#39;TOP&#39;, 2.0);</code></pre></p><h3>mirrorAcrossPlane(point, normal)</h3><p>Returns a mirrored clone across a plane defined by a point and normal. <pre><code>js
128
+ const mirrored = solid.mirrorAcrossPlane([0, 0, 0], [1, 0, 0]);</code></pre></p><h3>pushFace(faceName, distance)</h3><p>Translates a face along its outward normal using current triangle windings. <pre><code>js
129
+ solid.pushFace(&#39;FRONT&#39;, 1.5);</code></pre></p><h2>Manifold, orientation, and welding</h2><h3>setEpsilon(epsilon)</h3><p>Sets weld tolerance and optionally welds existing vertices, then fixes triangle winding. <pre><code>js
130
+ solid.setEpsilon(0.001);</code></pre></p><h3>_weldVerticesByEpsilon(epsilon)</h3><p>Internal: welds vertices on a grid using <code>epsilon</code>, drops degenerate triangles, and marks dirty. <pre><code>js
131
+ solid._weldVerticesByEpsilon(0.0005);</code></pre></p><h3>fixTriangleWindingsByAdjacency()</h3><p>Ensures shared edges have opposite orientation so the mesh is coherently oriented. <pre><code>js
132
+ solid.fixTriangleWindingsByAdjacency();</code></pre></p><h3>_isCoherentlyOrientedManifold()</h3><p>Checks whether every undirected edge is shared by two triangles with opposite directions. <pre><code>js
133
+ const ok = solid._isCoherentlyOrientedManifold();</code></pre></p><h3>invertNormals()</h3><p>Flips all triangles (swaps indices 1 and 2) and rebuilds the manifold cache. <pre><code>js
134
+ solid.invertNormals();</code></pre></p><h3>_manifoldize()</h3><p>Builds or returns the cached <code>Manifold</code> from authored arrays (fixes winding and orientation first). <pre><code>js
135
+ const manifold = solid._manifoldize();</code></pre></p><h2>Mesh cleanup and refinement</h2><h3>remesh({ maxEdgeLength, maxIterations })</h3><p>Splits edges longer than <code>maxEdgeLength</code>, preserving face IDs, and fixes winding after changes. <pre><code>js
136
+ solid.remesh({
137
+ maxEdgeLength: 5, // required threshold
138
+ maxIterations: 2 // optional passes (default 10)
139
+ });</code></pre></p><h3>removeSmallIslands({ maxTriangles, removeInternal, removeExternal })</h3><p>Deletes small connected triangle components relative to the largest shell; returns count removed. <pre><code>js
140
+ const removed = solid.removeSmallIslands({
141
+ maxTriangles: 20, // island size threshold
142
+ removeInternal: true, // drop islands inside main shell
143
+ removeExternal: true // drop islands outside main shell
144
+ });</code></pre></p><h3>removeSmallInternalIslands(maxTriangles)</h3><p>Convenience wrapper removing only internal islands under the given triangle count. <pre><code>js
145
+ solid.removeSmallInternalIslands(15);</code></pre></p><h3>removeTinyBoundaryTriangles(areaThreshold, maxIterations?)</h3><p>Performs edge flips across inter-face boundaries to remove triangles below <code>areaThreshold</code>. <pre><code>js
146
+ solid.removeTinyBoundaryTriangles(0.001, 3);</code></pre></p><h3>collapseTinyTriangles(lengthThreshold)</h3><p>Collapses triangles whose shortest edge is below <code>lengthThreshold</code>, then cleans up via a bounding-box intersect; returns number of edge collapses. <pre><code>js
147
+ const collapses = solid.collapseTinyTriangles(0.05);</code></pre></p><h3>splitSelfIntersectingTriangles(diagnostics?)</h3><p>Detects intersecting triangle pairs and subdivides them in place while preserving face IDs; returns splits applied. <pre><code>js
148
+ solid.splitSelfIntersectingTriangles();</code></pre></p><h3>removeDegenerateTriangles()</h3><p>Drops triangles with duplicate vertices or near-zero area; returns removed count. <pre><code>js
149
+ const removed = solid.removeDegenerateTriangles();</code></pre></p><h3>removeInternalTriangles()</h3><p>Rebuilds authoring arrays from the manifold’s exterior surface, removing internal faces; returns removed count. <pre><code>js
150
+ solid.removeInternalTriangles();</code></pre></p><h3>removeInternalTrianglesByRaycast()</h3><p>Uses centroid ray tests to cull triangles inside the solid without requiring manifoldization; returns removed count. <pre><code>js
151
+ solid.removeInternalTrianglesByRaycast();</code></pre></p><h3>removeInternalTrianglesByWinding(options?)</h3><p>Uses solid-angle winding numbers at triangle centroids to delete interior triangles; returns removed count. <pre><code>js
152
+ solid.removeInternalTrianglesByWinding({
153
+ offsetScale: 1e-4, // centroid offset relative to bbox diagonal
154
+ crossingTolerance: 0.05 // tolerance for interior crossing test
155
+ });</code></pre></p><h2>Queries and measurements</h2><h3>getMesh()</h3><p>Returns a fresh MeshGL view (<code>{ vertProperties, triVerts, faceID }</code>) from the cached manifold. <pre><code>js
156
+ const mesh = solid.getMesh();
157
+ console.log(mesh.triVerts.length / 3, &#39;triangles&#39;);
158
+ mesh.delete?.(); // cleanup when finished</code></pre></p><h3>_ensureFaceIndex()</h3><p>Internal: builds a cache mapping face IDs to triangle indices for fast lookups. <pre><code>js
159
+ solid._ensureFaceIndex();</code></pre></p><h3>getFace(name)</h3><p>Returns the triangles for a face label with positions and indices. <pre><code>js
160
+ const tris = solid.getFace(&#39;TOP&#39;);</code></pre></p><h3>getFaces(includeEmpty?)</h3><p>Enumerates all faces as <code>{ faceName, triangles }</code>, optionally including faces with no triangles. <pre><code>js
161
+ const faces = solid.getFaces();</code></pre></p><h3>getBoundaryEdgePolylines()</h3><p>Extracts boundary polylines between differing face labels. <pre><code>js
162
+ const edges = solid.getBoundaryEdgePolylines();</code></pre></p><h3>getTriangleCount()</h3><p>Counts triangles in the current manifold mesh. <pre><code>js
163
+ const triCount = solid.getTriangleCount();</code></pre></p><h3>volume()</h3><p>Computes absolute volume from the manifold mesh. <pre><code>js
164
+ const vol = solid.volume();</code></pre></p><h3>surfaceArea()</h3><p>Computes total surface area from the manifold mesh. <pre><code>js
165
+ const area = solid.surfaceArea();</code></pre></p><h2>Boolean and reconstruction helpers</h2><h3>_combineIdMaps(other)</h3><p>Internal: merges face ID → name maps before constructing boolean results. <pre><code>js
166
+ const mergedMap = solid._combineIdMaps(otherSolid);</code></pre></p><h3>union(other) / subtract(other) / intersect(other) / difference(other)</h3><p>Runs the corresponding boolean CSG against <code>other</code>, returning a new Solid with merged face labels, metadata, and aux edges. The boolean result also collapses duplicate face IDs that share the same face name so boundaries are generated by label, not by stale IDs. <pre><code>js
167
+ const united = solid.union(otherSolid);
168
+ const cut = solid.subtract(toolSolid);
169
+ const common = solid.intersect(otherSolid);
170
+ const diff = solid.difference(otherSolid); // alias of subtract</code></pre></p><h3>setTolerance(tolerance)</h3><p>Returns a new Solid built from <code>Manifold.setTolerance(tolerance)</code> to adjust robustness. <pre><code>js
171
+ const tolerant = solid.setTolerance(0.02);</code></pre></p><h3>simplify(tolerance?, updateInPlace?)</h3><p>Calls <code>Manifold.simplify</code>; when <code>updateInPlace</code> is truthy the current solid is mutated, otherwise a new one is returned. <pre><code>js
172
+ const simplified = solid.simplify(0.5); // new Solid
173
+ solid.simplify(0.5, true); // mutate in place</code></pre></p><h3>_expandTriIDsFromMesh(mesh) (static)</h3><p>Static helper that expands <code>faceID</code> on a MeshGL to a JS array, defaulting to zeros when absent. <pre><code>js
174
+ const ids = Solid._expandTriIDsFromMesh(mesh);</code></pre></p><h3>_fromManifold(manifoldObj, idToFaceName) (static)</h3><p>Static constructor that builds a Solid from an existing <code>Manifold</code> plus an ID → face-name map. <pre><code>js
175
+ const rebuilt = Solid._fromManifold(existingManifold, existingMap);</code></pre></p><h2>Export and visualization</h2><h3>toSTL(name?, precision?)</h3><p>Generates an ASCII STL string from the current manifold mesh. <pre><code>js
176
+ const stl = solid.toSTL(&#39;part&#39;, 5);</code></pre></p><h3>writeSTL(filePath, name?, precision?)</h3><p>Node-only helper that writes the STL string to disk. <pre><code>js
177
+ await solid.writeSTL(&#39;out/part.stl&#39;, &#39;part&#39;, 6);</code></pre></p><h3>visualize(options?)</h3><p>Clears children, builds one <code>Face</code> mesh per face label, and optional boundary <code>Edge</code> polylines; attaches them as children for display. <pre><code>js
178
+ solid.visualize({
179
+ showEdges: true, // include boundary polylines
180
+ forceAuthoring: false, // force authoring arrays instead of manifold mesh
181
+ authoringOnly: false // skip manifold path entirely
182
+ });
183
+ scene.add(solid);</code></pre></p><h2>Feature builders</h2><h3>chamfer(options)</h3><p>Asynchronously applies chamfers to named edges, returning a new Solid (union for OUTSET, subtract for INSET). <pre><code>js
184
+ const chamfered = await solid.chamfer({
185
+ distance: 1, // required
186
+ edgeNames: [&#39;EDGE_0&#39;], // edges to chamfer
187
+ direction: &#39;INSET&#39;, // or &#39;OUTSET&#39;
188
+ inflate: 0.1, // tool inflation (negated for OUTSET)
189
+ debug: false,
190
+ featureID: &#39;CHAMFER&#39;, // name prefix
191
+ sampleCount: undefined, // optional strip sampling override
192
+ snapSeamToEdge: undefined, // optional seam snapping
193
+ sideStripSubdiv: undefined, // optional side strip subdivisions
194
+ seamInsetScale: undefined, // optional seam inset scale
195
+ flipSide: undefined, // optional side flip
196
+ debugStride: undefined // optional debug stride
197
+ });</code></pre></p><h3>fillet(options)</h3><p>Applies constant-radius fillets to edges on this Solid (union for OUTSET, subtract for INSET). Accepts edge names or resolved edge objects; OUTSET can optionally hull shared corners into a single tool to avoid gaps. <pre><code>js
198
+ const filleted = await solid.fillet({
199
+ radius: 2, // required
200
+ edgeNames: [&#39;EDGE_0&#39;], // or edges: [edgeObj]
201
+ direction: &#39;OUTSET&#39;, // or &#39;INSET&#39;
202
+ resolution: 48, // segments around the tube
203
+ inflate: 0.05, // tangency/cap offset; closed loops skip the wedge inset
204
+ combineEdges: true, // OUTSET only; hulls fillets that share endpoints
205
+ showTangentOverlays: false, // add tangency overlays on the helper tube (debug-friendly)
206
+ debug: false,
207
+ featureID: &#39;FILLET&#39; // name prefix
208
+ });</code></pre></p>
209
+ </div>
210
+ </section>
211
+ </main>
212
+ <script>
213
+ (() => {
214
+ const searchInput = document.getElementById("doc-search");
215
+ const resultsBox = document.getElementById("doc-search-results");
216
+ const resultsList = document.getElementById("doc-search-list");
217
+ const statusEl = document.getElementById("doc-search-status");
218
+ const clearBtn = document.getElementById("doc-search-clear");
219
+ if (!searchInput || !resultsBox || !resultsList || !statusEl || !clearBtn) return;
220
+ const indexUrl = "./search-index.json";
221
+ let indexPromise = null;
222
+ let cachedEntries = null;
223
+
224
+ const escapeHtml = (text = "") =>
225
+ text
226
+ .replace(/&/g, "&amp;")
227
+ .replace(/</g, "&lt;")
228
+ .replace(/>/g, "&gt;");
229
+
230
+ const escapeRegExp = (text = "") => text.replace(/[.*+?^{}()|[]\$]/g, "\$&");
231
+
232
+ const highlight = (text, terms) => {
233
+ if (!terms.length) return escapeHtml(text);
234
+ const pattern = terms.map(escapeRegExp).join("|");
235
+ const regex = new RegExp(`(${pattern})`, "gi");
236
+ return escapeHtml(text).replace(regex, "<mark>$1</mark>");
237
+ };
238
+
239
+ const buildSnippet = (entry, terms) => {
240
+ const source = entry.content || entry.summary || "";
241
+ if (!source) return { plain: "", highlighted: "" };
242
+ let hit = source.length;
243
+ for (const term of terms) {
244
+ const idx = entry.contentLower.indexOf(term);
245
+ if (idx !== -1 && idx < hit) hit = idx;
246
+ }
247
+ if (!Number.isFinite(hit) || hit === source.length) hit = 0;
248
+ const start = Math.max(0, hit - 60);
249
+ const end = Math.min(source.length, hit + 140);
250
+ const snippet = source.slice(start, end);
251
+ return { plain: snippet, highlighted: highlight(snippet, terms) };
252
+ };
253
+
254
+ const updateStatus = (message) => {
255
+ statusEl.textContent = message;
256
+ };
257
+
258
+ const loadIndex = async () => {
259
+ if (cachedEntries) return cachedEntries;
260
+ if (!indexPromise) {
261
+ indexPromise = fetch(indexUrl, { cache: "no-store" })
262
+ .then((res) => {
263
+ if (!res.ok) throw new Error("Failed to load search index");
264
+ return res.json();
265
+ })
266
+ .then((json) => {
267
+ cachedEntries = Array.isArray(json)
268
+ ? json.map((entry) => ({
269
+ ...entry,
270
+ contentLower: (entry.content || "").toLowerCase(),
271
+ titleLower: (entry.title || "").toLowerCase(),
272
+ }))
273
+ : [];
274
+ return cachedEntries;
275
+ })
276
+ .catch((err) => {
277
+ console.error("Search index load failed", err);
278
+ cachedEntries = [];
279
+ throw err;
280
+ });
281
+ }
282
+ return indexPromise;
283
+ };
284
+
285
+ const renderResults = (entries, terms) => {
286
+ if (!terms.length) {
287
+ resultsBox.hidden = true;
288
+ return;
289
+ }
290
+ if (!entries.length) {
291
+ resultsList.innerHTML = '<li class="search-item"><div class="search-snippet">No matches found.</div></li>';
292
+ resultsBox.hidden = false;
293
+ return;
294
+ }
295
+ const rendered = entries
296
+ .slice(0, 30)
297
+ .map((entry) => {
298
+ const snippet = buildSnippet(entry, terms);
299
+ const title = highlight(entry.title || entry.href, terms);
300
+ const hasFragment = snippet.plain && snippet.plain.trim().length > 0;
301
+ const fragment = hasFragment ? `#:~:text=${encodeURIComponent(snippet.plain.trim())}` : "";
302
+ const hrefWithFragment = hasFragment
303
+ ? (entry.href.includes("#") ? `${entry.href}&:~:text=${encodeURIComponent(snippet.plain.trim())}` : `${entry.href}${fragment}`)
304
+ : entry.href;
305
+ const snippetHtml = snippet.highlighted ? `<div class="search-snippet">${snippet.highlighted}</div>` : "";
306
+ return `<li class="search-item"><a href="${hrefWithFragment}">${title}</a>${snippetHtml}</li>`;
307
+ })
308
+ .join("");
309
+ resultsList.innerHTML = rendered;
310
+ resultsBox.hidden = false;
311
+ };
312
+
313
+ const performSearch = async () => {
314
+ const rawQuery = searchInput.value.trim();
315
+ if (rawQuery.length < 2) {
316
+ updateStatus("Type at least 2 characters to search.");
317
+ resultsBox.hidden = true;
318
+ return;
319
+ }
320
+ const terms = rawQuery.toLowerCase().split(/\s+/).filter(Boolean);
321
+ updateStatus("Searching...");
322
+ try {
323
+ const entries = await loadIndex();
324
+ const matches = entries.filter((entry) =>
325
+ terms.every((term) => entry.contentLower.includes(term) || entry.titleLower.includes(term))
326
+ );
327
+ renderResults(matches, terms);
328
+ updateStatus(matches.length ? `${matches.length} result${matches.length === 1 ? "" : "s"} for "${rawQuery}"` : "No matches found.");
329
+ } catch (err) {
330
+ updateStatus("Search unavailable (could not load index).");
331
+ }
332
+ };
333
+
334
+ searchInput.addEventListener("input", performSearch);
335
+
336
+ searchInput.addEventListener("focus", () => {
337
+ if (!cachedEntries) {
338
+ loadIndex().catch(() => updateStatus("Search unavailable (could not load index)."));
339
+ }
340
+ });
341
+
342
+ clearBtn.addEventListener("click", () => {
343
+ searchInput.value = "";
344
+ resultsBox.hidden = true;
345
+ updateStatus("Type at least 2 characters to search.");
346
+ searchInput.focus();
347
+ });
348
+
349
+ document.addEventListener("keydown", (evt) => {
350
+ if (evt.key === "Escape" && document.activeElement === searchInput) {
351
+ searchInput.value = "";
352
+ resultsBox.hidden = true;
353
+ updateStatus("Type at least 2 characters to search.");
354
+ }
355
+ });
356
+ })();
357
+ </script>
358
+ </body>
359
+ </html>