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,258 @@
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>BREP Kernel 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>BREP Kernel Reference</h1><p>This page catalogs the core classes and helpers that make up the BREP kernel (everything under <code>src/BREP</code>). Use it alongside <code>docs/solid-methods.md</code> for <code>Solid</code> details and <code>docs/brep-api.md</code> for the export map.</p><h2>Core types</h2><ul><li><strong>Solid / Face / Edge / Vertex</strong> – Geometry + selection primitives (<code>Solid</code> API in <code>docs/solid-methods.md</code>).</li><li><strong>AssemblyComponent</strong> – Groups one or more solids for the assembly constraint solver. Options: <code>{ name=&#39;Component&#39;, fixed=false }</code>.</li></ul><h2>Primitives (<code>src/BREP/primitives.js</code>)</h2><p>All extend <code>Solid</code> and immediately generate geometry.</p><ul><li><code>Cube({ x=1, y=1, z=1, name })</code></li><li><code>Pyramid({ bL=1, s=4, h=1, name })</code> (<code>s</code> is side count ≥ 3)</li><li><code>Sphere({ r=1, resolution=24, name })</code></li><li><code>Cylinder({ radius=1, height=1, resolution=32, name })</code></li><li><code>Cone({ r1=0.5, r2=1, h=1, resolution=32, name })</code></li><li><code>Torus({ mR=2, tR=0.5, resolution=48, arcDegrees=360, name })</code></li></ul><h2>Feature solids</h2><p>- <strong>ExtrudeSolid</strong> – <code>{ face, distance=1 | dir:Vector3, distanceBack=0, name=&#39;Extrude&#39; }</code>.</p><ul><li><strong>Sweep</strong> – <code>{ face, sweepPathEdges=[], distance=1, distanceBack=0, mode=&#39;translate&#39;, name=&#39;Sweep&#39;, omitBaseCap=false }</code>.</li><li><strong>Revolve</strong> – <code>{ face, axis, angle=360, resolution=64, name=&#39;Revolve&#39; }</code>.</li><li><strong>TubeSolid (Tube)</strong> – <code>{ points=[], radius=1, innerRadius=0, resolution=32, closed=false, name=&#39;Tube&#39; }</code>.</li></ul><p>- <strong>ChamferSolid</strong> – <code>{ edgeToChamfer, distance=1, sampleCount=50, snapSeamToEdge=true, sideStripSubdiv=8, seamInsetScale=1e-3, direction=&#39;INSET&#39;|&#39;OUTSET&#39;, inflate=0, flipSide=false, debug=false, debugStride=12 }</code>.</p><ul><li><strong>OffsetShellSolid.generate(sourceSolid, distance, { newSolidName, featureId=&#39;OffsetShell&#39; })</strong> – Static helper to build offset shells.</li></ul><h2>Fillet utilities (<code>src/BREP/fillets/fillet.js</code>)</h2><p>- <code>filletSolid({ edgeToFillet, radius, sideMode=&#39;INSET&#39;|&#39;OUTSET&#39;, inflate=0.1, resolution=32, showTangentOverlays=false, debug=false, name=&#39;fillet&#39; })</code> – Builds wedge/tube helpers and returns <code>{ finalSolid, tube, wedge }</code>; overlays add tangency polylines to the tube for debugging/PMI tagging.</p><ul><li><code>computeFilletCenterline(edgeObj, radius, sideMode)</code> – Returns centerline/tangents/edge polylines plus a <code>closedLoop</code> flag.</li><li><code>attachFilletCenterlineAuxEdge(solid, edgeObj, radius, sideMode=&#39;INSET&#39;, name=&#39;FILLET_CENTERLINE&#39;, options)</code> – Adds centerline as an aux edge; <code>options</code> mirrors <code>Solid.addAuxEdge</code>.</li></ul><h2>Boolean helper</h2><p>- <code>applyBooleanOperation(partHistory, baseSolid, booleanParam, featureID)</code> – Runs <code>UNION|INTERSECT|SUBTRACT</code> between <code>baseSolid</code> and <code>booleanParam.targets</code> (objects or names). Returns <code>{ added, removed }</code>. Subtract semantics invert: each target subtracts the new base.</p><h2>Conversion and repair</h2><ul><li><strong>MeshToBrep</strong> – <code>new MeshToBrep(geometryOrMesh, faceDeflectionAngle=30, weldTolerance=1e-5)</code> groups triangles into faces based on normal deflection and welds shared vertices.</li><li><strong>MeshRepairer</strong> – Per-geometry repair pipeline:</li><p>- <code>weldVertices(geometry, epsilon=1e-4)</code> - <code>fixTJunctions(geometry, lineEps=5e-4, gridCell=0.01)</code> - <code>removeOverlappingTriangles(geometry, posEps=1e-6)</code> - <code>fillHoles(geometry)</code> - <code>fixTriangleNormals(geometry)</code> - <code>repairAll(geometry, { weldEps=5e-4, lineEps=5e-4, gridCell=0.01 })</code></p><li><strong>Point cloud wrapper</strong> – <code>buildTightPointCloudWrap(rawPoints, { padding=0.02*diag, alphaRadius=0.6*medianKNN })</code> builds a solid via marching cubes over a density field.</li></ul><h2>Misc helpers</h2><ul><li><strong>MeshToBrep</strong>, <strong>MeshRepairer</strong>, <strong>applyBooleanOperation</strong>, <strong>PointCloudWrap</strong> live in <code>src/BREP</code> and are re-exported via <code>BREP.js</code> (<code>docs/brep-api.md</code>).</li><li><strong>SolidMethod docs</strong> – <code>docs/solid-methods.md</code> covers all core operations (authoring, cleanup, booleans, export).</li></ul><h2>Example: boolean with primitives</h2><p><pre><code>js
98
+ import { BREP } from &#39;../src/BREP/BREP.js&#39;;
99
+
100
+ const box = new BREP.Cube({ x: 20, y: 10, z: 10, name: &#39;Box&#39; });
101
+ const hole = new BREP.Cylinder({ radius: 3, height: 10, name: &#39;Hole&#39; });
102
+ hole.position.set(10, 5, 0);
103
+ hole.bakeTransform(hole.matrixWorld);
104
+
105
+ const result = box.subtract(hole);
106
+ result.name = &#39;BoxWithHole&#39;;
107
+ result.visualize();</code></pre></p>
108
+ </div>
109
+ </section>
110
+ </main>
111
+ <script>
112
+ (() => {
113
+ const searchInput = document.getElementById("doc-search");
114
+ const resultsBox = document.getElementById("doc-search-results");
115
+ const resultsList = document.getElementById("doc-search-list");
116
+ const statusEl = document.getElementById("doc-search-status");
117
+ const clearBtn = document.getElementById("doc-search-clear");
118
+ if (!searchInput || !resultsBox || !resultsList || !statusEl || !clearBtn) return;
119
+ const indexUrl = "./search-index.json";
120
+ let indexPromise = null;
121
+ let cachedEntries = null;
122
+
123
+ const escapeHtml = (text = "") =>
124
+ text
125
+ .replace(/&/g, "&amp;")
126
+ .replace(/</g, "&lt;")
127
+ .replace(/>/g, "&gt;");
128
+
129
+ const escapeRegExp = (text = "") => text.replace(/[.*+?^{}()|[]\$]/g, "\$&");
130
+
131
+ const highlight = (text, terms) => {
132
+ if (!terms.length) return escapeHtml(text);
133
+ const pattern = terms.map(escapeRegExp).join("|");
134
+ const regex = new RegExp(`(${pattern})`, "gi");
135
+ return escapeHtml(text).replace(regex, "<mark>$1</mark>");
136
+ };
137
+
138
+ const buildSnippet = (entry, terms) => {
139
+ const source = entry.content || entry.summary || "";
140
+ if (!source) return { plain: "", highlighted: "" };
141
+ let hit = source.length;
142
+ for (const term of terms) {
143
+ const idx = entry.contentLower.indexOf(term);
144
+ if (idx !== -1 && idx < hit) hit = idx;
145
+ }
146
+ if (!Number.isFinite(hit) || hit === source.length) hit = 0;
147
+ const start = Math.max(0, hit - 60);
148
+ const end = Math.min(source.length, hit + 140);
149
+ const snippet = source.slice(start, end);
150
+ return { plain: snippet, highlighted: highlight(snippet, terms) };
151
+ };
152
+
153
+ const updateStatus = (message) => {
154
+ statusEl.textContent = message;
155
+ };
156
+
157
+ const loadIndex = async () => {
158
+ if (cachedEntries) return cachedEntries;
159
+ if (!indexPromise) {
160
+ indexPromise = fetch(indexUrl, { cache: "no-store" })
161
+ .then((res) => {
162
+ if (!res.ok) throw new Error("Failed to load search index");
163
+ return res.json();
164
+ })
165
+ .then((json) => {
166
+ cachedEntries = Array.isArray(json)
167
+ ? json.map((entry) => ({
168
+ ...entry,
169
+ contentLower: (entry.content || "").toLowerCase(),
170
+ titleLower: (entry.title || "").toLowerCase(),
171
+ }))
172
+ : [];
173
+ return cachedEntries;
174
+ })
175
+ .catch((err) => {
176
+ console.error("Search index load failed", err);
177
+ cachedEntries = [];
178
+ throw err;
179
+ });
180
+ }
181
+ return indexPromise;
182
+ };
183
+
184
+ const renderResults = (entries, terms) => {
185
+ if (!terms.length) {
186
+ resultsBox.hidden = true;
187
+ return;
188
+ }
189
+ if (!entries.length) {
190
+ resultsList.innerHTML = '<li class="search-item"><div class="search-snippet">No matches found.</div></li>';
191
+ resultsBox.hidden = false;
192
+ return;
193
+ }
194
+ const rendered = entries
195
+ .slice(0, 30)
196
+ .map((entry) => {
197
+ const snippet = buildSnippet(entry, terms);
198
+ const title = highlight(entry.title || entry.href, terms);
199
+ const hasFragment = snippet.plain && snippet.plain.trim().length > 0;
200
+ const fragment = hasFragment ? `#:~:text=${encodeURIComponent(snippet.plain.trim())}` : "";
201
+ const hrefWithFragment = hasFragment
202
+ ? (entry.href.includes("#") ? `${entry.href}&:~:text=${encodeURIComponent(snippet.plain.trim())}` : `${entry.href}${fragment}`)
203
+ : entry.href;
204
+ const snippetHtml = snippet.highlighted ? `<div class="search-snippet">${snippet.highlighted}</div>` : "";
205
+ return `<li class="search-item"><a href="${hrefWithFragment}">${title}</a>${snippetHtml}</li>`;
206
+ })
207
+ .join("");
208
+ resultsList.innerHTML = rendered;
209
+ resultsBox.hidden = false;
210
+ };
211
+
212
+ const performSearch = async () => {
213
+ const rawQuery = searchInput.value.trim();
214
+ if (rawQuery.length < 2) {
215
+ updateStatus("Type at least 2 characters to search.");
216
+ resultsBox.hidden = true;
217
+ return;
218
+ }
219
+ const terms = rawQuery.toLowerCase().split(/\s+/).filter(Boolean);
220
+ updateStatus("Searching...");
221
+ try {
222
+ const entries = await loadIndex();
223
+ const matches = entries.filter((entry) =>
224
+ terms.every((term) => entry.contentLower.includes(term) || entry.titleLower.includes(term))
225
+ );
226
+ renderResults(matches, terms);
227
+ updateStatus(matches.length ? `${matches.length} result${matches.length === 1 ? "" : "s"} for "${rawQuery}"` : "No matches found.");
228
+ } catch (err) {
229
+ updateStatus("Search unavailable (could not load index).");
230
+ }
231
+ };
232
+
233
+ searchInput.addEventListener("input", performSearch);
234
+
235
+ searchInput.addEventListener("focus", () => {
236
+ if (!cachedEntries) {
237
+ loadIndex().catch(() => updateStatus("Search unavailable (could not load index)."));
238
+ }
239
+ });
240
+
241
+ clearBtn.addEventListener("click", () => {
242
+ searchInput.value = "";
243
+ resultsBox.hidden = true;
244
+ updateStatus("Type at least 2 characters to search.");
245
+ searchInput.focus();
246
+ });
247
+
248
+ document.addEventListener("keydown", (evt) => {
249
+ if (evt.key === "Escape" && document.activeElement === searchInput) {
250
+ searchInput.value = "";
251
+ resultsBox.hidden = true;
252
+ updateStatus("Type at least 2 characters to search.");
253
+ }
254
+ });
255
+ })();
256
+ </script>
257
+ </body>
258
+ </html>
@@ -0,0 +1,248 @@
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>BREP Model and Classes - 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>BREP Model and Classes</h1><h2>Overview</h2><ul><li>BREP combines a triangle mesh with per-triangle face labels. Labels map to globally unique IDs in Manifold so selections survive boolean operations.</li><li>During manifoldization, triangle windings are made consistent, outward orientation is enforced, and an optional weld epsilon deduplicates vertices.</li><li>Visualization builds one mesh per face label and edge polylines for label boundaries, enabling semantic selection in the UI and PMI tooling.</li></ul><h2>Solid</h2><ul><li><code>Solid</code> is a <code>THREE.Group</code> subclass that handles authoring, CSG, queries, and export.</li><li>Geometry storage uses <code>_vertProperties</code> (flat positions), <code>_triVerts</code> (triangle indices), and <code>_triIDs</code> (face IDs) plus name-to-ID maps.</li><li>Key methods include <code>addTriangle</code>, <code>setEpsilon</code>, <code>mirrorAcrossPlane</code>, <code>invertNormals</code>, <code>fixTriangleWindingsByAdjacency</code>, <code>removeTinyBoundaryTriangles</code>, <code>getMesh</code>, <code>getFace</code>, <code>getFaces</code>, <code>getFaceNames</code>, <code>getBoundaryEdgePolylines</code>, <code>visualize</code>, <code>union</code>, <code>subtract</code>, <code>intersect</code>, <code>difference</code>, <code>simplify</code>, <code>setTolerance</code>, <code>volume</code>, <code>surfaceArea</code>, <code>toSTL</code>, and <code>writeSTL</code>.</li><li>Full per-method descriptions and examples live in <code>docs/solid-methods.md</code>.</li></ul><h2>Face</h2><ul><li><code>Face</code> is a <code>THREE.Mesh</code> representing all triangles that share a label.</li><li>Provides <code>getAverageNormal()</code> and <code>surfaceArea()</code> helpers for inspection and downstream logic.</li></ul><h2>Edge</h2><ul><li><code>Edge</code> instances represent boundary polylines between two face labels and expose metadata describing the adjacent faces.</li><li>Use edges for PMI dimension snapping, measurement, and preview visualization.</li></ul><p>Additional implementation details can be explored in <code>src/BREP/BetterSolid.js</code> and related helpers.</p>
98
+ </div>
99
+ </section>
100
+ </main>
101
+ <script>
102
+ (() => {
103
+ const searchInput = document.getElementById("doc-search");
104
+ const resultsBox = document.getElementById("doc-search-results");
105
+ const resultsList = document.getElementById("doc-search-list");
106
+ const statusEl = document.getElementById("doc-search-status");
107
+ const clearBtn = document.getElementById("doc-search-clear");
108
+ if (!searchInput || !resultsBox || !resultsList || !statusEl || !clearBtn) return;
109
+ const indexUrl = "./search-index.json";
110
+ let indexPromise = null;
111
+ let cachedEntries = null;
112
+
113
+ const escapeHtml = (text = "") =>
114
+ text
115
+ .replace(/&/g, "&amp;")
116
+ .replace(/</g, "&lt;")
117
+ .replace(/>/g, "&gt;");
118
+
119
+ const escapeRegExp = (text = "") => text.replace(/[.*+?^{}()|[]\$]/g, "\$&");
120
+
121
+ const highlight = (text, terms) => {
122
+ if (!terms.length) return escapeHtml(text);
123
+ const pattern = terms.map(escapeRegExp).join("|");
124
+ const regex = new RegExp(`(${pattern})`, "gi");
125
+ return escapeHtml(text).replace(regex, "<mark>$1</mark>");
126
+ };
127
+
128
+ const buildSnippet = (entry, terms) => {
129
+ const source = entry.content || entry.summary || "";
130
+ if (!source) return { plain: "", highlighted: "" };
131
+ let hit = source.length;
132
+ for (const term of terms) {
133
+ const idx = entry.contentLower.indexOf(term);
134
+ if (idx !== -1 && idx < hit) hit = idx;
135
+ }
136
+ if (!Number.isFinite(hit) || hit === source.length) hit = 0;
137
+ const start = Math.max(0, hit - 60);
138
+ const end = Math.min(source.length, hit + 140);
139
+ const snippet = source.slice(start, end);
140
+ return { plain: snippet, highlighted: highlight(snippet, terms) };
141
+ };
142
+
143
+ const updateStatus = (message) => {
144
+ statusEl.textContent = message;
145
+ };
146
+
147
+ const loadIndex = async () => {
148
+ if (cachedEntries) return cachedEntries;
149
+ if (!indexPromise) {
150
+ indexPromise = fetch(indexUrl, { cache: "no-store" })
151
+ .then((res) => {
152
+ if (!res.ok) throw new Error("Failed to load search index");
153
+ return res.json();
154
+ })
155
+ .then((json) => {
156
+ cachedEntries = Array.isArray(json)
157
+ ? json.map((entry) => ({
158
+ ...entry,
159
+ contentLower: (entry.content || "").toLowerCase(),
160
+ titleLower: (entry.title || "").toLowerCase(),
161
+ }))
162
+ : [];
163
+ return cachedEntries;
164
+ })
165
+ .catch((err) => {
166
+ console.error("Search index load failed", err);
167
+ cachedEntries = [];
168
+ throw err;
169
+ });
170
+ }
171
+ return indexPromise;
172
+ };
173
+
174
+ const renderResults = (entries, terms) => {
175
+ if (!terms.length) {
176
+ resultsBox.hidden = true;
177
+ return;
178
+ }
179
+ if (!entries.length) {
180
+ resultsList.innerHTML = '<li class="search-item"><div class="search-snippet">No matches found.</div></li>';
181
+ resultsBox.hidden = false;
182
+ return;
183
+ }
184
+ const rendered = entries
185
+ .slice(0, 30)
186
+ .map((entry) => {
187
+ const snippet = buildSnippet(entry, terms);
188
+ const title = highlight(entry.title || entry.href, terms);
189
+ const hasFragment = snippet.plain && snippet.plain.trim().length > 0;
190
+ const fragment = hasFragment ? `#:~:text=${encodeURIComponent(snippet.plain.trim())}` : "";
191
+ const hrefWithFragment = hasFragment
192
+ ? (entry.href.includes("#") ? `${entry.href}&:~:text=${encodeURIComponent(snippet.plain.trim())}` : `${entry.href}${fragment}`)
193
+ : entry.href;
194
+ const snippetHtml = snippet.highlighted ? `<div class="search-snippet">${snippet.highlighted}</div>` : "";
195
+ return `<li class="search-item"><a href="${hrefWithFragment}">${title}</a>${snippetHtml}</li>`;
196
+ })
197
+ .join("");
198
+ resultsList.innerHTML = rendered;
199
+ resultsBox.hidden = false;
200
+ };
201
+
202
+ const performSearch = async () => {
203
+ const rawQuery = searchInput.value.trim();
204
+ if (rawQuery.length < 2) {
205
+ updateStatus("Type at least 2 characters to search.");
206
+ resultsBox.hidden = true;
207
+ return;
208
+ }
209
+ const terms = rawQuery.toLowerCase().split(/\s+/).filter(Boolean);
210
+ updateStatus("Searching...");
211
+ try {
212
+ const entries = await loadIndex();
213
+ const matches = entries.filter((entry) =>
214
+ terms.every((term) => entry.contentLower.includes(term) || entry.titleLower.includes(term))
215
+ );
216
+ renderResults(matches, terms);
217
+ updateStatus(matches.length ? `${matches.length} result${matches.length === 1 ? "" : "s"} for "${rawQuery}"` : "No matches found.");
218
+ } catch (err) {
219
+ updateStatus("Search unavailable (could not load index).");
220
+ }
221
+ };
222
+
223
+ searchInput.addEventListener("input", performSearch);
224
+
225
+ searchInput.addEventListener("focus", () => {
226
+ if (!cachedEntries) {
227
+ loadIndex().catch(() => updateStatus("Search unavailable (could not load index)."));
228
+ }
229
+ });
230
+
231
+ clearBtn.addEventListener("click", () => {
232
+ searchInput.value = "";
233
+ resultsBox.hidden = true;
234
+ updateStatus("Type at least 2 characters to search.");
235
+ searchInput.focus();
236
+ });
237
+
238
+ document.addEventListener("keydown", (evt) => {
239
+ if (evt.key === "Escape" && document.activeElement === searchInput) {
240
+ searchInput.value = "";
241
+ resultsBox.hidden = true;
242
+ updateStatus("Type at least 2 characters to search.");
243
+ }
244
+ });
245
+ })();
246
+ </script>
247
+ </body>
248
+ </html>