brep-io-kernel 1.0.0-ci.10

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 (271) hide show
  1. package/LICENSE.md +32 -0
  2. package/README.md +157 -0
  3. package/dist-kernel/brep-kernel.js +74699 -0
  4. package/package.json +58 -0
  5. package/src/BREP/AssemblyComponent.js +42 -0
  6. package/src/BREP/BREP.js +43 -0
  7. package/src/BREP/BetterSolid.js +805 -0
  8. package/src/BREP/Edge.js +103 -0
  9. package/src/BREP/Extrude.js +403 -0
  10. package/src/BREP/Face.js +187 -0
  11. package/src/BREP/MeshRepairer.js +634 -0
  12. package/src/BREP/OffsetShellSolid.js +614 -0
  13. package/src/BREP/PointCloudWrap.js +302 -0
  14. package/src/BREP/Revolve.js +345 -0
  15. package/src/BREP/SolidMethods/authoring.js +112 -0
  16. package/src/BREP/SolidMethods/booleanOps.js +230 -0
  17. package/src/BREP/SolidMethods/chamfer.js +122 -0
  18. package/src/BREP/SolidMethods/edgeResolution.js +25 -0
  19. package/src/BREP/SolidMethods/fillet.js +792 -0
  20. package/src/BREP/SolidMethods/index.js +72 -0
  21. package/src/BREP/SolidMethods/io.js +105 -0
  22. package/src/BREP/SolidMethods/lifecycle.js +103 -0
  23. package/src/BREP/SolidMethods/manifoldOps.js +375 -0
  24. package/src/BREP/SolidMethods/meshCleanup.js +2512 -0
  25. package/src/BREP/SolidMethods/meshQueries.js +264 -0
  26. package/src/BREP/SolidMethods/metadata.js +106 -0
  27. package/src/BREP/SolidMethods/metrics.js +51 -0
  28. package/src/BREP/SolidMethods/transforms.js +361 -0
  29. package/src/BREP/SolidMethods/visualize.js +508 -0
  30. package/src/BREP/SolidShared.js +26 -0
  31. package/src/BREP/Sweep.js +1596 -0
  32. package/src/BREP/Tube.js +857 -0
  33. package/src/BREP/Vertex.js +43 -0
  34. package/src/BREP/applyBooleanOperation.js +704 -0
  35. package/src/BREP/boundsUtils.js +48 -0
  36. package/src/BREP/chamfer.js +551 -0
  37. package/src/BREP/edgePolylineUtils.js +85 -0
  38. package/src/BREP/fillets/common.js +388 -0
  39. package/src/BREP/fillets/fillet.js +1422 -0
  40. package/src/BREP/fillets/filletGeometry.js +15 -0
  41. package/src/BREP/fillets/inset.js +389 -0
  42. package/src/BREP/fillets/offsetHelper.js +143 -0
  43. package/src/BREP/fillets/outset.js +88 -0
  44. package/src/BREP/helix.js +193 -0
  45. package/src/BREP/meshToBrep.js +234 -0
  46. package/src/BREP/primitives.js +279 -0
  47. package/src/BREP/setupManifold.js +71 -0
  48. package/src/BREP/threadGeometry.js +1120 -0
  49. package/src/BREP/triangleUtils.js +8 -0
  50. package/src/BREP/triangulate.js +608 -0
  51. package/src/FeatureRegistry.js +183 -0
  52. package/src/PartHistory.js +1132 -0
  53. package/src/UI/AccordionWidget.js +292 -0
  54. package/src/UI/CADmaterials.js +850 -0
  55. package/src/UI/EnvMonacoEditor.js +522 -0
  56. package/src/UI/FloatingWindow.js +396 -0
  57. package/src/UI/HistoryWidget.js +457 -0
  58. package/src/UI/MainToolbar.js +131 -0
  59. package/src/UI/ModelLibraryView.js +194 -0
  60. package/src/UI/OrthoCameraIdle.js +206 -0
  61. package/src/UI/PluginsWidget.js +280 -0
  62. package/src/UI/SceneListing.js +606 -0
  63. package/src/UI/SelectionFilter.js +629 -0
  64. package/src/UI/ViewCube.js +389 -0
  65. package/src/UI/assembly/AssemblyConstraintCollectionWidget.js +329 -0
  66. package/src/UI/assembly/AssemblyConstraintControlsWidget.js +282 -0
  67. package/src/UI/assembly/AssemblyConstraintsWidget.css +292 -0
  68. package/src/UI/assembly/AssemblyConstraintsWidget.js +1373 -0
  69. package/src/UI/assembly/constraintFaceUtils.js +115 -0
  70. package/src/UI/assembly/constraintHighlightUtils.js +70 -0
  71. package/src/UI/assembly/constraintLabelUtils.js +31 -0
  72. package/src/UI/assembly/constraintPointUtils.js +64 -0
  73. package/src/UI/assembly/constraintSelectionUtils.js +185 -0
  74. package/src/UI/assembly/constraintStatusUtils.js +142 -0
  75. package/src/UI/componentSelectorModal.js +240 -0
  76. package/src/UI/controls/CombinedTransformControls.js +386 -0
  77. package/src/UI/dialogs.js +351 -0
  78. package/src/UI/expressionsManager.js +100 -0
  79. package/src/UI/featureDialogWidgets/booleanField.js +25 -0
  80. package/src/UI/featureDialogWidgets/booleanOperationField.js +97 -0
  81. package/src/UI/featureDialogWidgets/buttonField.js +45 -0
  82. package/src/UI/featureDialogWidgets/componentSelectorField.js +102 -0
  83. package/src/UI/featureDialogWidgets/defaultField.js +23 -0
  84. package/src/UI/featureDialogWidgets/fileField.js +66 -0
  85. package/src/UI/featureDialogWidgets/index.js +34 -0
  86. package/src/UI/featureDialogWidgets/numberField.js +165 -0
  87. package/src/UI/featureDialogWidgets/optionsField.js +33 -0
  88. package/src/UI/featureDialogWidgets/referenceSelectionField.js +208 -0
  89. package/src/UI/featureDialogWidgets/stringField.js +24 -0
  90. package/src/UI/featureDialogWidgets/textareaField.js +28 -0
  91. package/src/UI/featureDialogWidgets/threadDesignationField.js +160 -0
  92. package/src/UI/featureDialogWidgets/transformField.js +252 -0
  93. package/src/UI/featureDialogWidgets/utils.js +43 -0
  94. package/src/UI/featureDialogWidgets/vec3Field.js +133 -0
  95. package/src/UI/featureDialogs.js +1414 -0
  96. package/src/UI/fileManagerWidget.js +615 -0
  97. package/src/UI/history/HistoryCollectionWidget.js +1294 -0
  98. package/src/UI/history/historyCollectionWidget.css.js +257 -0
  99. package/src/UI/history/historyDisplayInfo.js +133 -0
  100. package/src/UI/mobile.js +28 -0
  101. package/src/UI/objectDump.js +442 -0
  102. package/src/UI/pmi/AnnotationCollectionWidget.js +120 -0
  103. package/src/UI/pmi/AnnotationHistory.js +353 -0
  104. package/src/UI/pmi/AnnotationRegistry.js +90 -0
  105. package/src/UI/pmi/BaseAnnotation.js +269 -0
  106. package/src/UI/pmi/LabelOverlay.css +102 -0
  107. package/src/UI/pmi/LabelOverlay.js +191 -0
  108. package/src/UI/pmi/PMIMode.js +1550 -0
  109. package/src/UI/pmi/PMIViewsWidget.js +1098 -0
  110. package/src/UI/pmi/annUtils.js +729 -0
  111. package/src/UI/pmi/dimensions/AngleDimensionAnnotation.js +647 -0
  112. package/src/UI/pmi/dimensions/ExplodeBodyAnnotation.js +507 -0
  113. package/src/UI/pmi/dimensions/HoleCalloutAnnotation.js +462 -0
  114. package/src/UI/pmi/dimensions/LeaderAnnotation.js +403 -0
  115. package/src/UI/pmi/dimensions/LinearDimensionAnnotation.js +532 -0
  116. package/src/UI/pmi/dimensions/NoteAnnotation.js +110 -0
  117. package/src/UI/pmi/dimensions/RadialDimensionAnnotation.js +659 -0
  118. package/src/UI/pmi/pmiStyle.js +44 -0
  119. package/src/UI/sketcher/SketchMode3D.js +4095 -0
  120. package/src/UI/sketcher/dimensions.js +674 -0
  121. package/src/UI/sketcher/glyphs.js +236 -0
  122. package/src/UI/sketcher/highlights.js +60 -0
  123. package/src/UI/toolbarButtons/aboutButton.js +5 -0
  124. package/src/UI/toolbarButtons/exportButton.js +609 -0
  125. package/src/UI/toolbarButtons/flatPatternButton.js +307 -0
  126. package/src/UI/toolbarButtons/importButton.js +160 -0
  127. package/src/UI/toolbarButtons/inspectorToggleButton.js +12 -0
  128. package/src/UI/toolbarButtons/metadataButton.js +1063 -0
  129. package/src/UI/toolbarButtons/orientToFaceButton.js +114 -0
  130. package/src/UI/toolbarButtons/registerDefaultButtons.js +46 -0
  131. package/src/UI/toolbarButtons/saveButton.js +99 -0
  132. package/src/UI/toolbarButtons/scriptRunnerButton.js +302 -0
  133. package/src/UI/toolbarButtons/testsButton.js +26 -0
  134. package/src/UI/toolbarButtons/undoRedoButtons.js +25 -0
  135. package/src/UI/toolbarButtons/wireframeToggleButton.js +5 -0
  136. package/src/UI/toolbarButtons/zoomToFitButton.js +5 -0
  137. package/src/UI/triangleDebuggerWindow.js +945 -0
  138. package/src/UI/viewer.js +4228 -0
  139. package/src/assemblyConstraints/AssemblyConstraintHistory.js +1576 -0
  140. package/src/assemblyConstraints/AssemblyConstraintRegistry.js +120 -0
  141. package/src/assemblyConstraints/BaseAssemblyConstraint.js +66 -0
  142. package/src/assemblyConstraints/constraintExpressionUtils.js +35 -0
  143. package/src/assemblyConstraints/constraintUtils/parallelAlignment.js +676 -0
  144. package/src/assemblyConstraints/constraints/AngleConstraint.js +485 -0
  145. package/src/assemblyConstraints/constraints/CoincidentConstraint.js +194 -0
  146. package/src/assemblyConstraints/constraints/DistanceConstraint.js +616 -0
  147. package/src/assemblyConstraints/constraints/FixedConstraint.js +78 -0
  148. package/src/assemblyConstraints/constraints/ParallelConstraint.js +252 -0
  149. package/src/assemblyConstraints/constraints/TouchAlignConstraint.js +961 -0
  150. package/src/core/entities/HistoryCollectionBase.js +72 -0
  151. package/src/core/entities/ListEntityBase.js +109 -0
  152. package/src/core/entities/schemaProcesser.js +121 -0
  153. package/src/exporters/sheetMetalFlatPattern.js +659 -0
  154. package/src/exporters/sheetMetalUnfold.js +862 -0
  155. package/src/exporters/step.js +1135 -0
  156. package/src/exporters/threeMF.js +575 -0
  157. package/src/features/assemblyComponent/AssemblyComponentFeature.js +780 -0
  158. package/src/features/boolean/BooleanFeature.js +94 -0
  159. package/src/features/chamfer/ChamferFeature.js +116 -0
  160. package/src/features/datium/DatiumFeature.js +80 -0
  161. package/src/features/edgeFeatureUtils.js +41 -0
  162. package/src/features/extrude/ExtrudeFeature.js +143 -0
  163. package/src/features/fillet/FilletFeature.js +197 -0
  164. package/src/features/helix/HelixFeature.js +405 -0
  165. package/src/features/hole/HoleFeature.js +1050 -0
  166. package/src/features/hole/screwClearance.js +86 -0
  167. package/src/features/hole/threadDesignationCatalog.js +149 -0
  168. package/src/features/imageHeightSolid/ImageHeightmapSolidFeature.js +463 -0
  169. package/src/features/imageToFace/ImageToFaceFeature.js +727 -0
  170. package/src/features/imageToFace/imageEditor.js +1270 -0
  171. package/src/features/imageToFace/traceUtils.js +971 -0
  172. package/src/features/import3dModel/Import3dModelFeature.js +151 -0
  173. package/src/features/loft/LoftFeature.js +605 -0
  174. package/src/features/mirror/MirrorFeature.js +151 -0
  175. package/src/features/offsetFace/OffsetFaceFeature.js +370 -0
  176. package/src/features/offsetShell/OffsetShellFeature.js +89 -0
  177. package/src/features/overlapCleanup/OverlapCleanupFeature.js +85 -0
  178. package/src/features/pattern/PatternFeature.js +275 -0
  179. package/src/features/patternLinear/PatternLinearFeature.js +120 -0
  180. package/src/features/patternRadial/PatternRadialFeature.js +186 -0
  181. package/src/features/plane/PlaneFeature.js +154 -0
  182. package/src/features/primitiveCone/primitiveConeFeature.js +99 -0
  183. package/src/features/primitiveCube/primitiveCubeFeature.js +70 -0
  184. package/src/features/primitiveCylinder/primitiveCylinderFeature.js +91 -0
  185. package/src/features/primitivePyramid/primitivePyramidFeature.js +72 -0
  186. package/src/features/primitiveSphere/primitiveSphereFeature.js +62 -0
  187. package/src/features/primitiveTorus/primitiveTorusFeature.js +109 -0
  188. package/src/features/remesh/RemeshFeature.js +97 -0
  189. package/src/features/revolve/RevolveFeature.js +111 -0
  190. package/src/features/selectionUtils.js +118 -0
  191. package/src/features/sheetMetal/SheetMetalContourFlangeFeature.js +1656 -0
  192. package/src/features/sheetMetal/SheetMetalCutoutFeature.js +1056 -0
  193. package/src/features/sheetMetal/SheetMetalFlangeFeature.js +1568 -0
  194. package/src/features/sheetMetal/SheetMetalHemFeature.js +43 -0
  195. package/src/features/sheetMetal/SheetMetalObject.js +141 -0
  196. package/src/features/sheetMetal/SheetMetalTabFeature.js +176 -0
  197. package/src/features/sheetMetal/UNFOLD_NEUTRAL_REQUIREMENTS.md +153 -0
  198. package/src/features/sheetMetal/contour-flange-rebuild-spec.md +261 -0
  199. package/src/features/sheetMetal/profileUtils.js +25 -0
  200. package/src/features/sheetMetal/sheetMetalCleanup.js +9 -0
  201. package/src/features/sheetMetal/sheetMetalFaceTypes.js +146 -0
  202. package/src/features/sheetMetal/sheetMetalMetadata.js +165 -0
  203. package/src/features/sheetMetal/sheetMetalPipeline.js +169 -0
  204. package/src/features/sheetMetal/sheetMetalProfileUtils.js +216 -0
  205. package/src/features/sheetMetal/sheetMetalTabUtils.js +29 -0
  206. package/src/features/sheetMetal/sheetMetalTree.js +210 -0
  207. package/src/features/sketch/SketchFeature.js +955 -0
  208. package/src/features/sketch/sketchSolver2D/ConstraintEngine.js +800 -0
  209. package/src/features/sketch/sketchSolver2D/constraintDefinitions.js +704 -0
  210. package/src/features/sketch/sketchSolver2D/mathHelpersMod.js +307 -0
  211. package/src/features/spline/SplineEditorSession.js +988 -0
  212. package/src/features/spline/SplineFeature.js +1388 -0
  213. package/src/features/spline/splineUtils.js +218 -0
  214. package/src/features/sweep/SweepFeature.js +110 -0
  215. package/src/features/transform/TransformFeature.js +152 -0
  216. package/src/features/tube/TubeFeature.js +635 -0
  217. package/src/fs.proxy.js +625 -0
  218. package/src/idbStorage.js +254 -0
  219. package/src/index.js +12 -0
  220. package/src/main.js +15 -0
  221. package/src/metadataManager.js +64 -0
  222. package/src/path.proxy.js +277 -0
  223. package/src/plugins/ghLoader.worker.js +151 -0
  224. package/src/plugins/pluginManager.js +286 -0
  225. package/src/pmi/PMIViewsManager.js +134 -0
  226. package/src/services/componentLibrary.js +198 -0
  227. package/src/tests/ConsoleCapture.js +189 -0
  228. package/src/tests/S7-diagnostics-2025-12-23T18-37-23-570Z.json +630 -0
  229. package/src/tests/browserTests.js +597 -0
  230. package/src/tests/debugBoolean.js +225 -0
  231. package/src/tests/partFiles/badBoolean.json +957 -0
  232. package/src/tests/partFiles/extrudeTest.json +88 -0
  233. package/src/tests/partFiles/filletFail.json +58 -0
  234. package/src/tests/partFiles/import_TEst.part.part.json +646 -0
  235. package/src/tests/partFiles/sheetMetalHem.BREP.json +734 -0
  236. package/src/tests/test_boolean_subtract.js +27 -0
  237. package/src/tests/test_chamfer.js +17 -0
  238. package/src/tests/test_extrudeFace.js +24 -0
  239. package/src/tests/test_fillet.js +17 -0
  240. package/src/tests/test_fillet_nonClosed.js +45 -0
  241. package/src/tests/test_filletsMoreDifficult.js +46 -0
  242. package/src/tests/test_history_features_basic.js +149 -0
  243. package/src/tests/test_hole.js +282 -0
  244. package/src/tests/test_mirror.js +16 -0
  245. package/src/tests/test_offsetShellGrouping.js +85 -0
  246. package/src/tests/test_plane.js +4 -0
  247. package/src/tests/test_primitiveCone.js +11 -0
  248. package/src/tests/test_primitiveCube.js +7 -0
  249. package/src/tests/test_primitiveCylinder.js +8 -0
  250. package/src/tests/test_primitivePyramid.js +9 -0
  251. package/src/tests/test_primitiveSphere.js +17 -0
  252. package/src/tests/test_primitiveTorus.js +21 -0
  253. package/src/tests/test_pushFace.js +126 -0
  254. package/src/tests/test_sheetMetalContourFlange.js +125 -0
  255. package/src/tests/test_sheetMetal_features.js +80 -0
  256. package/src/tests/test_sketch_openLoop.js +45 -0
  257. package/src/tests/test_solidMetrics.js +58 -0
  258. package/src/tests/test_stlLoader.js +1889 -0
  259. package/src/tests/test_sweepFace.js +55 -0
  260. package/src/tests/test_tube.js +45 -0
  261. package/src/tests/test_tube_closedLoop.js +67 -0
  262. package/src/tests/tests.js +493 -0
  263. package/src/tools/assemblyConstraintDialogCapturePage.js +56 -0
  264. package/src/tools/dialogCapturePageFactory.js +227 -0
  265. package/src/tools/featureDialogCapturePage.js +47 -0
  266. package/src/tools/pmiAnnotationDialogCapturePage.js +60 -0
  267. package/src/utils/axisHelpers.js +99 -0
  268. package/src/utils/deepClone.js +69 -0
  269. package/src/utils/geometryTolerance.js +37 -0
  270. package/src/utils/normalizeTypeString.js +8 -0
  271. package/src/utils/xformMath.js +51 -0
@@ -0,0 +1,97 @@
1
+
2
+
3
+ const inputParamsSchema = {
4
+ id: {
5
+ type: "string",
6
+ default_value: null,
7
+ hint: "unique identifier for the remesh feature",
8
+ },
9
+ targetSolid: {
10
+ type: "reference_selection",
11
+ selectionFilter: ["SOLID"],
12
+ multiple: false,
13
+ default_value: null,
14
+ hint: "Select a solid to remesh (clone is created)",
15
+ },
16
+ mode: {
17
+ type: "options",
18
+ options: ["Increase resolution", "Simplify"],
19
+ default_value: "Increase resolution",
20
+ hint: "Choose remeshing mode",
21
+ },
22
+ maxEdgeLength: {
23
+ type: "number",
24
+ step: 0.1,
25
+ default_value: 1,
26
+ hint: "Split edges longer than this length",
27
+ },
28
+ maxIterations: {
29
+ type: "number",
30
+ step: 1,
31
+ default_value: 10,
32
+ hint: "Maximum refinement passes",
33
+ },
34
+ tolerance: {
35
+ type: "number",
36
+ step: 0.1,
37
+ default_value: 0.1,
38
+ hint: "Simplify tolerance (used in Simplify mode)",
39
+ },
40
+ };
41
+
42
+ export class RemeshFeature {
43
+ static shortName = "RM";
44
+ static longName = "Remesh";
45
+ static inputParamsSchema = inputParamsSchema;
46
+
47
+ constructor() {
48
+ this.inputParams = {};
49
+ this.persistentData = {};
50
+ }
51
+
52
+ async run(partHistory) {
53
+ const scene = partHistory.scene;
54
+
55
+ // Resolve target solid
56
+ const targetEntry = Array.isArray(this.inputParams.targetSolid)
57
+ ? (this.inputParams.targetSolid[0] || null)
58
+ : (this.inputParams.targetSolid || null);
59
+ const target = (targetEntry && typeof targetEntry === 'object')
60
+ ? targetEntry
61
+ : (targetEntry ? await scene.getObjectByName(String(targetEntry)) : null);
62
+
63
+ if (!target || target.type !== 'SOLID') return { added: [], removed: [] };
64
+
65
+ const modeRaw = this.inputParams.mode || 'Increase resolution';
66
+ const mode = String(modeRaw).toLowerCase();
67
+
68
+ // Clone target to preserve original
69
+ const outSolid = target.clone();
70
+
71
+ if (mode === 'simplify') {
72
+ const T = Number(this.inputParams.tolerance);
73
+ const tol = Number.isFinite(T) && T >= 0 ? T : undefined;
74
+ try {
75
+ if (tol === undefined) outSolid.simplify();
76
+ else outSolid.simplify(tol);
77
+ } catch (e) {
78
+ console.warn('[RemeshFeature] Simplify failed; returning original clone.', e);
79
+ }
80
+ } else {
81
+ const L = Number(this.inputParams.maxEdgeLength);
82
+ const I = Number(this.inputParams.maxIterations);
83
+ const maxEdgeLength = (Number.isFinite(L) && L > 0) ? L : 1;
84
+ const maxIterations = (Number.isFinite(I) && I > 0) ? I : 10;
85
+ try { outSolid.remesh({ maxEdgeLength, maxIterations }); } catch (e) {
86
+ console.warn('[RemeshFeature] Remesh failed; returning original clone.', e);
87
+ }
88
+ }
89
+
90
+ // Name and visualize for UI
91
+ try { outSolid.name = `(${target.name || 'Solid'})`; } catch (_) {}
92
+ try { outSolid.visualize(); } catch (_) {}
93
+
94
+ try { target.__removeFlag = true; } catch {}
95
+ return { added: [outSolid], removed: [target] };
96
+ }
97
+ }
@@ -0,0 +1,111 @@
1
+ import { BREP } from "../../BREP/BREP.js";
2
+ import { selectionHasSketch } from "../selectionUtils.js";
3
+
4
+ const inputParamsSchema = {
5
+ id: {
6
+ type: "string",
7
+ default_value: null,
8
+ hint: "unique identifier for the revolve feature",
9
+ },
10
+ profile: {
11
+ type: "reference_selection",
12
+ selectionFilter: ["SKETCH", "FACE"],
13
+ multiple: false,
14
+ default_value: null,
15
+ hint: "Select the profile (face) to revolve",
16
+ },
17
+ consumeProfileSketch: {
18
+ type: "boolean",
19
+ default_value: true,
20
+ hint: "Remove the referenced sketch after creating the revolve. Turn off to keep it in the scene.",
21
+ },
22
+ axis: {
23
+ type: "reference_selection",
24
+ selectionFilter: ["EDGE"],
25
+ multiple: false,
26
+ default_value: null,
27
+ hint: "Select the axis to revolve about",
28
+ },
29
+ angle: {
30
+ type: "number",
31
+ default_value: 360,
32
+ hint: "Revolve angle",
33
+ },
34
+ resolution: {
35
+ type: "number",
36
+ default_value: 64,
37
+ hint: "Number of segments used for the revolve sweep",
38
+ },
39
+ boolean: {
40
+ type: "boolean_operation",
41
+ default_value: { targets: [], operation: 'NONE' },
42
+ hint: "Optional boolean operation with selected solids"
43
+ }
44
+ };
45
+
46
+ export class RevolveFeature {
47
+ static shortName = "R";
48
+ static longName = "Revolve";
49
+ static inputParamsSchema = inputParamsSchema;
50
+
51
+ constructor() {
52
+ this.inputParams = {};
53
+ this.persistentData = {};
54
+ }
55
+
56
+ uiFieldsTest(context) {
57
+ const params = this.inputParams || context?.params || {};
58
+ const partHistory = context?.history || null;
59
+ return selectionHasSketch(params.profile, partHistory) ? [] : ["consumeProfileSketch"];
60
+ }
61
+
62
+ async run(partHistory) {
63
+ const { profile, axis, angle, resolution } = this.inputParams;
64
+
65
+ // Resolve profile object: accept FACE or SKETCH group object
66
+ const obj = Array.isArray(profile) ? (profile[0] || null) : (profile || null);
67
+ let faceObj = obj;
68
+ if (obj && obj.type === 'SKETCH') {
69
+ faceObj = obj.children.find(ch => ch.type === 'FACE') || obj.children.find(ch => ch.userData?.faceName);
70
+ }
71
+ if (!faceObj || !faceObj.geometry) return { added: [], removed: [] };
72
+ // if the face is a child of a sketch we need to remove the sketch from the scene
73
+
74
+ const axisObj = Array.isArray(axis) ? (axis[0] || null) : (axis || null);
75
+ if (!axisObj) {
76
+ console.warn("RevolveFeature: no axis selected");
77
+ return { added: [], removed: [] };
78
+ }
79
+ if (!faceObj) {
80
+ console.warn("RevolveFeature: no profile face found");
81
+ return { added: [], removed: [] };
82
+ }
83
+
84
+ const removed = [];
85
+ const consumeSketch = this.inputParams?.consumeProfileSketch !== false;
86
+ if (consumeSketch && faceObj && faceObj.type === 'FACE' && faceObj.parent && faceObj.parent.type === 'SKETCH') {
87
+ removed.push(faceObj.parent);
88
+ }
89
+
90
+ const revolve = new BREP.Revolve({
91
+ face: faceObj,
92
+ axis: axisObj,
93
+ angle,
94
+ resolution,
95
+ name: this.inputParams.featureID,
96
+ });
97
+
98
+ // Weld slight numerical seams and build mesh
99
+ try { revolve.setEpsilon(1e-6); } catch { }
100
+ revolve.visualize();
101
+ const effects = await BREP.applyBooleanOperation(partHistory || {}, revolve, this.inputParams.boolean, this.inputParams.featureID);
102
+ const booleanRemoved = Array.isArray(effects.removed) ? effects.removed : [];
103
+ const removedArtifacts = [...removed, ...booleanRemoved];
104
+ // Flag removals (sketch parent + boolean effects)
105
+ try { for (const obj of removedArtifacts) { if (obj) obj.__removeFlag = true; } } catch { }
106
+ return {
107
+ added: Array.isArray(effects.added) ? effects.added : [],
108
+ removed: removedArtifacts,
109
+ };
110
+ }
111
+ }
@@ -0,0 +1,118 @@
1
+ export function resolveSelectionObject(selection, partHistory) {
2
+ if (!selection) return null;
3
+ if (typeof selection === 'string') {
4
+ if (partHistory && typeof partHistory.getObjectByName === 'function') {
5
+ return partHistory.getObjectByName(selection);
6
+ }
7
+ const scene = partHistory?.scene;
8
+ if (scene && typeof scene.getObjectByName === 'function') {
9
+ return scene.getObjectByName(selection);
10
+ }
11
+ return null;
12
+ }
13
+ return selection;
14
+ }
15
+
16
+ function getFeatureEntryId(entry) {
17
+ if (!entry || typeof entry !== 'object') return null;
18
+ const params = entry.inputParams || {};
19
+ const rawId = params.id ?? params.featureID ?? entry.id ?? null;
20
+ if (rawId == null) return null;
21
+ return String(rawId);
22
+ }
23
+
24
+ function isSketchFeatureType(type, partHistory) {
25
+ const raw = type == null ? '' : String(type).trim();
26
+ if (!raw) return false;
27
+ const upper = raw.toUpperCase();
28
+ if (upper === 'S' || upper === 'SKETCH' || upper === 'SKETCHFEATURE') return true;
29
+
30
+ const registry = partHistory?.featureRegistry;
31
+ if (!registry || typeof registry.getSafe !== 'function') return false;
32
+ const cls = registry.getSafe(raw);
33
+ if (!cls) return false;
34
+ const shortName = String(cls.shortName || '').toUpperCase();
35
+ const longName = String(cls.longName || '').toUpperCase();
36
+ const className = String(cls.name || '').toUpperCase();
37
+ if (shortName === 'S' || longName.includes('SKETCH') || className.includes('SKETCH')) return true;
38
+ if (shortName === 'SP' || className.includes('SPLINE')) return true;
39
+ if (shortName === 'IMAGE' || className.includes('IMAGETOFACE')) return true;
40
+ return false;
41
+ }
42
+
43
+ function isSketchFeatureId(partHistory, refName) {
44
+ if (!partHistory || !Array.isArray(partHistory.features)) return false;
45
+ const target = String(refName);
46
+ for (const entry of partHistory.features) {
47
+ const entryId = getFeatureEntryId(entry);
48
+ if (entryId !== target) continue;
49
+ if (isSketchFeatureType(entry?.type, partHistory)) return true;
50
+ }
51
+ return false;
52
+ }
53
+
54
+ export function selectionHasSketch(selection, partHistory) {
55
+ const list = Array.isArray(selection) ? selection : [selection];
56
+ for (const item of list) {
57
+ if (!item) continue;
58
+ if (typeof item === 'string') {
59
+ const raw = item.trim();
60
+ if (!raw) continue;
61
+ const base = raw.split(/[:|\[]/, 1)[0];
62
+ if (base && isSketchFeatureId(partHistory, base)) return true;
63
+ }
64
+ const obj = resolveSelectionObject(item, partHistory);
65
+ if (!obj) continue;
66
+ if (obj.type === 'SKETCH') return true;
67
+ if (obj.parent && obj.parent.type === 'SKETCH') return true;
68
+ if (obj.name) {
69
+ const base = String(obj.name).split(/[:|\[]/, 1)[0];
70
+ if (base && isSketchFeatureId(partHistory, base)) return true;
71
+ }
72
+ }
73
+ return false;
74
+ }
75
+
76
+ export function normalizeSelectionName(value) {
77
+ if (value == null) return null;
78
+
79
+ if (typeof value === 'string') {
80
+ const trimmed = value.trim();
81
+ if (!trimmed) return null;
82
+ try {
83
+ const parsed = JSON.parse(trimmed);
84
+ if (parsed && typeof parsed === 'object') {
85
+ const parsedName = typeof parsed.name === 'string' ? parsed.name.trim() : '';
86
+ if (parsedName) return parsedName;
87
+ const parsedId = typeof parsed.id === 'string' ? parsed.id.trim() : '';
88
+ if (parsedId) return parsedId;
89
+ }
90
+ } catch { /* not JSON */ }
91
+ return trimmed;
92
+ }
93
+
94
+ if (typeof value === 'object') {
95
+ if (typeof value.name === 'string' && value.name.trim()) return value.name.trim();
96
+ if (typeof value.id === 'string' && value.id.trim()) return value.id.trim();
97
+ if (Array.isArray(value.path)) {
98
+ const joined = value.path.filter(Boolean).map(String).join(' > ');
99
+ if (joined) return joined;
100
+ }
101
+ }
102
+
103
+ const asString = String(value);
104
+ return asString.trim() || null;
105
+ }
106
+
107
+ export function normalizeSelectionList(values) {
108
+ if (!Array.isArray(values)) return [];
109
+ const seen = new Set();
110
+ const out = [];
111
+ for (const item of values) {
112
+ const normalized = normalizeSelectionName(item);
113
+ if (!normalized || seen.has(normalized)) continue;
114
+ seen.add(normalized);
115
+ out.push(normalized);
116
+ }
117
+ return out;
118
+ }