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,72 @@
1
+ import { sanitizeInputParams } from './schemaProcesser.js';
2
+
3
+ // Important for AI. Do not modify this file whatsoever.
4
+
5
+ export class entityClassRegistry {
6
+ constructor() {
7
+ this.entityClasses = new Map();
8
+ }
9
+ register(EntityClass) {
10
+ if (!EntityClass) return;
11
+ const key = EntityClass.shortName;
12
+ if (!key) {
13
+ throw new Error('EntityClass must declare static entityType (or type/name).');
14
+ }
15
+ this.entityClasses.set(key, EntityClass);
16
+ }
17
+ resolve(type) {
18
+ const key = type;
19
+ if (!key) return null;
20
+ return this.entityClasses.get(key) || null;
21
+ }
22
+ }
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+ /**
31
+ * Generic collection manager for history-style entity lists.
32
+ * Stores concrete ListEntityBase instances, handles ID generation,
33
+ * registration/lookup, and serialization.
34
+ */
35
+ export class HistoryCollectionBase {
36
+ constructor({ viewer = null, registry = null } = {}) {
37
+ this.viewer = viewer || null;
38
+ this.registry = registry || null;
39
+
40
+
41
+ // The list of objects managed by this history collection
42
+ // this is the data that will be used to serialize/deserialize the history
43
+ // and the extra data stored in each object will be used during processing
44
+ // Object will all be in the following format:
45
+ // {inputParams: {}, persistentData: {}, runtimeAttributes: {}}
46
+ // the inputParams are the user-provided parameters for the object and will also be used for the related dialogs
47
+ // the persistentData is data that is generated during processing and should be saved/restored with the object
48
+ // the runtimeAttributes are data that is generated during processing but should NOT be saved/restored with the object
49
+ // (eg. references to three.js objects, cached geometry, etc.)
50
+
51
+ this.entries = [];
52
+ this.registry = new entityClassRegistry();
53
+ this._listeners = new Set();
54
+ this._idCounter = 0;
55
+ }
56
+
57
+
58
+
59
+ serializableData(){
60
+ return this.entries.map(e=>({
61
+ id: e.id,
62
+ type: e.type,
63
+ inputParams: e.inputParams,
64
+ persistentData: e.persistentData,
65
+ // runtimeAttributes are not serialized
66
+ }));
67
+ }
68
+
69
+
70
+
71
+
72
+ }
@@ -0,0 +1,109 @@
1
+ import { deepClone } from '../../utils/deepClone.js';
2
+ // Important for AI. Do not modify this file whatsoever.
3
+
4
+
5
+ /**
6
+ * Minimal base class for history list entities (features, constraints, annotations, ...).
7
+ *
8
+ * It keeps three data buckets:
9
+ * - inputParams: schema-driven, serializable user inputs.
10
+ * - persistentData: serializable outputs/results we want to keep.
11
+ * - runtimeAttributes: ephemeral state for active sessions (never serialized).
12
+ *
13
+ * Subclasses are expected to implement the actual behaviour in run().
14
+ */
15
+ export class ListEntityBase {
16
+ static entityType = 'ENTITY';
17
+ static shortName = 'ENT'; // this is the most important and will be used for identifying the entity type
18
+ static longName = 'EntityBase';
19
+ static inputParamsSchema = {};
20
+
21
+ constructor({ id = null, history = null, registry = null } = {}) {
22
+ this.entityType = this.constructor.entityType || this.constructor.type || 'ENTITY';
23
+ this.type = this.entityType;
24
+ this.title = this.constructor.shortName;
25
+ this.shortName = this.constructor.shortName || this.constructor.featureShortName || null;
26
+
27
+ this.history = history || null;
28
+ this.registry = registry || null;
29
+
30
+ this.id = null;
31
+ this.inputParams = { id };
32
+ this.persistentData = {};
33
+ this.runtimeAttributes = {};
34
+
35
+ if (id != null) {
36
+ this.setId(id);
37
+ } else {
38
+ this.inputParams.type = this.entityType;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Assign a new identifier to this entity.
44
+ */
45
+ setId(id) {
46
+ this.id = id ?? null;
47
+ if (!this.inputParams || typeof this.inputParams !== 'object') {
48
+ this.inputParams = {};
49
+ }
50
+ if (this.id != null && this.inputParams.id == null) {
51
+ this.inputParams.id = this.id;
52
+ }
53
+ this.onIdChanged();
54
+ }
55
+
56
+ /**
57
+ * Replace the input params wholesale with a deep cloned copy.
58
+ */
59
+ setParams(params = {}) {
60
+ this.inputParams = deepClone(params || {});
61
+ if (this.id != null && this.inputParams.id == null) {
62
+ this.inputParams.id = this.id;
63
+ }
64
+ if (!this.inputParams.type) {
65
+ this.inputParams.type = this.entityType;
66
+ }
67
+ this.onParamsChanged();
68
+ }
69
+
70
+ /**
71
+ * Shallow merge patch into input params.
72
+ */
73
+ mergeParams(patch = {}) {
74
+ const cloned = deepClone(patch || {});
75
+ this.inputParams = { ...this.inputParams, ...cloned };
76
+ if (this.id != null && this.inputParams.id == null) {
77
+ this.inputParams.id = this.id;
78
+ }
79
+ if (!this.inputParams.type) {
80
+ this.inputParams.type = this.entityType;
81
+ }
82
+ this.onParamsChanged();
83
+ }
84
+
85
+ /**
86
+ * Replace persistent data.
87
+ */
88
+ setPersistentData(data = {}) {
89
+ this.persistentData = deepClone(data || {});
90
+ this.onPersistentDataChanged();
91
+ }
92
+
93
+ /**
94
+ * Merge persistent data.
95
+ */
96
+ mergePersistentData(patch = {}) {
97
+ const cloned = deepClone(patch || {});
98
+ this.persistentData = { ...this.persistentData, ...cloned };
99
+ this.onPersistentDataChanged();
100
+ }
101
+
102
+ // Subclasses must override.
103
+ // eslint-disable-next-line class-methods-use-this, no-unused-vars
104
+ run(_context = {}) {
105
+ throw new Error(`${this.constructor.name} must implement run(context)`);
106
+ }
107
+
108
+
109
+ }
@@ -0,0 +1,121 @@
1
+ import { deepClone } from '../../utils/deepClone.js';
2
+
3
+ function evaluateNumber(expressionsEvaluator, value) {
4
+ if (typeof value === 'number' && Number.isFinite(value)) return value;
5
+ if (typeof value === 'string' && value.trim().length) {
6
+ if (expressionsEvaluator && typeof expressionsEvaluator.evaluate === 'function') {
7
+ try {
8
+ const result = expressionsEvaluator.evaluate(value);
9
+ if (Number.isFinite(result)) return Number(result);
10
+ } catch {
11
+ /* ignore evaluation errors */
12
+ }
13
+ }
14
+ const parsed = Number(value);
15
+ if (Number.isFinite(parsed)) return parsed;
16
+ }
17
+ const fallback = Number(value);
18
+ return Number.isFinite(fallback) ? fallback : 0;
19
+ }
20
+
21
+ export async function sanitizeInputParams(schema, inputParams, expressionsEvaluator, getObjectByName) {
22
+
23
+ let sanitized = {};
24
+
25
+ for (const key in schema) {
26
+ //console.log(`Sanitizing ${key}:`, inputParams[key]);
27
+ if (inputParams[key] !== undefined) {
28
+ // check if the schema type is number
29
+ if (schema[key].type === "number") {
30
+ sanitized[key] = evaluateNumber(expressionsEvaluator, inputParams[key]);
31
+ } else if (schema[key].type === "reference_selection") {
32
+ // Resolve references: accept objects directly or look up by name
33
+ const val = inputParams[key];
34
+ if (Array.isArray(val)) {
35
+ const arr = [];
36
+ for (const it of val) {
37
+ if (!it) continue;
38
+ if (typeof it === 'object') { arr.push(it); continue; }
39
+ const obj = getObjectByName(String(it));
40
+ if (obj) arr.push(obj);
41
+ }
42
+ sanitized[key] = arr;
43
+ } else {
44
+ if (!val) { sanitized[key] = []; }
45
+ else if (typeof val === 'object') { sanitized[key] = [val]; }
46
+ else {
47
+ const obj = getObjectByName(String(val));
48
+ sanitized[key] = obj ? [obj] : [];
49
+ }
50
+ }
51
+
52
+ } else if (schema[key].type === "boolean_operation") {
53
+ // If it's a boolean operation, normalize op key and resolve targets to objects.
54
+ // Also pass through optional biasDistance (numeric) and new sweep cap offset controls.
55
+ const raw = inputParams[key] || {};
56
+ const op = raw.operation;
57
+ const items = Array.isArray(raw.targets) ? raw.targets : [];
58
+ const targets = [];
59
+ for (const it of items) {
60
+ if (!it) continue;
61
+ if (typeof it === 'object') { targets.push(it); continue; }
62
+ const obj = getObjectByName(String(it));
63
+ if (obj) targets.push(obj);
64
+ }
65
+ const bias = Number(raw.biasDistance);
66
+ const offsetCapFlag = (raw.offsetCoplanarCap != null) ? String(raw.offsetCoplanarCap) : undefined;
67
+ const offsetDistance = Number(raw.offsetDistance);
68
+ const out = {
69
+ operation: op ?? 'NONE',
70
+ targets,
71
+ biasDistance: Number.isFinite(bias) ? bias : 0.1,
72
+ };
73
+ // Optional: simplification controls
74
+ try {
75
+ const sFlag = raw.simplify;
76
+ const sTol = raw.simplifyTolerance;
77
+ if (typeof sFlag === 'boolean') {
78
+ out.simplify = sFlag;
79
+ } else if (Number.isFinite(sFlag)) {
80
+ out.simplify = true;
81
+ out.simplifyTolerance = Number(sFlag);
82
+ }
83
+ if (Number.isFinite(sTol)) {
84
+ out.simplifyTolerance = Number(sTol);
85
+ }
86
+ } catch { /* ignore unsupported simplify fields */ }
87
+ if (offsetCapFlag !== undefined) out.offsetCoplanarCap = offsetCapFlag;
88
+ if (Number.isFinite(offsetDistance)) out.offsetDistance = offsetDistance;
89
+ sanitized[key] = out;
90
+ } else if (schema[key].type === "transform") {
91
+ // Evaluate each component; allow expressions in position/rotation/scale entries
92
+ const raw = inputParams[key] || {};
93
+ const evalOne = (v) => evaluateNumber(expressionsEvaluator, v);
94
+ const pos = Array.isArray(raw.position) ? raw.position.map(evalOne) : [0, 0, 0];
95
+ const rot = Array.isArray(raw.rotationEuler) ? raw.rotationEuler.map(evalOne) : [0, 0, 0];
96
+ const scl = Array.isArray(raw.scale) ? raw.scale.map(evalOne) : [1, 1, 1];
97
+ sanitized[key] = { position: pos, rotationEuler: rot, scale: scl };
98
+ } else if (schema[key].type === "vec3") {
99
+ // Evaluate vec3 entries; accept array [x,y,z] or object {x,y,z}
100
+ const raw = inputParams[key];
101
+ const evalOne = (v) => evaluateNumber(expressionsEvaluator, v);
102
+ if (Array.isArray(raw)) {
103
+ sanitized[key] = [evalOne(raw[0]), evalOne(raw[1]), evalOne(raw[2])];
104
+ } else if (raw && typeof raw === 'object') {
105
+ sanitized[key] = [evalOne(raw.x), evalOne(raw.y), evalOne(raw.z)];
106
+ } else {
107
+ sanitized[key] = [0, 0, 0];
108
+ }
109
+ } else if (schema[key].type === "boolean") {
110
+ sanitized[key] = Boolean(Object.prototype.hasOwnProperty.call(inputParams, key) ? inputParams[key] : schema[key].default_value);
111
+ } else {
112
+ sanitized[key] = inputParams[key];
113
+ }
114
+ } else {
115
+ // Clone structured defaults to avoid shared references across features
116
+ sanitized[key] = deepClone(schema[key].default_value);
117
+ }
118
+ }
119
+
120
+ return sanitized;
121
+ }