@constructorfleet/sketchforge-engine 1.26.0 → 1.28.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 (200) hide show
  1. package/dist/cadAnalysis.d.ts +94 -0
  2. package/dist/cadAnalysis.d.ts.map +1 -0
  3. package/dist/cadAnalysis.js +157 -0
  4. package/dist/cadAnalysis.js.map +1 -0
  5. package/dist/cadBakeMetadata.d.ts +11 -2
  6. package/dist/cadBakeMetadata.d.ts.map +1 -1
  7. package/dist/cadBakeMetadata.js +9 -0
  8. package/dist/cadBakeMetadata.js.map +1 -1
  9. package/dist/cadProjection.d.ts.map +1 -1
  10. package/dist/cadProjection.js.map +1 -1
  11. package/dist/cadSection.d.ts.map +1 -1
  12. package/dist/cadShell.d.ts +143 -0
  13. package/dist/cadShell.d.ts.map +1 -0
  14. package/dist/cadShell.js +313 -0
  15. package/dist/cadShell.js.map +1 -0
  16. package/dist/cadSolids.d.ts.map +1 -1
  17. package/dist/cadSolids.js +18 -1
  18. package/dist/cadSolids.js.map +1 -1
  19. package/dist/cutBrepFrameMigration.d.ts +46 -0
  20. package/dist/cutBrepFrameMigration.d.ts.map +1 -0
  21. package/dist/cutBrepFrameMigration.js +105 -0
  22. package/dist/cutBrepFrameMigration.js.map +1 -0
  23. package/dist/cutterPadding.d.ts.map +1 -1
  24. package/dist/domain/cameraProjection.js.map +1 -1
  25. package/dist/domain/sketchforge.d.ts +31 -1
  26. package/dist/domain/sketchforge.d.ts.map +1 -1
  27. package/dist/editorHistory.d.ts.map +1 -1
  28. package/dist/editorHistory.js.map +1 -1
  29. package/dist/engine.d.ts +3 -3
  30. package/dist/engine.d.ts.map +1 -1
  31. package/dist/engine.js +156 -78
  32. package/dist/engine.js.map +1 -1
  33. package/dist/exactBooleanParts.d.ts +4 -2
  34. package/dist/exactBooleanParts.d.ts.map +1 -1
  35. package/dist/exactBooleanParts.js +7 -3
  36. package/dist/exactBooleanParts.js.map +1 -1
  37. package/dist/exactBooleanSolids.d.ts.map +1 -1
  38. package/dist/gearProfile.d.ts.map +1 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/loftProfile.d.ts +1 -1
  44. package/dist/loftProfile.d.ts.map +1 -1
  45. package/dist/loftProfile.js.map +1 -1
  46. package/dist/meshEdgeProjection.d.ts +104 -0
  47. package/dist/meshEdgeProjection.d.ts.map +1 -0
  48. package/dist/meshEdgeProjection.js +439 -0
  49. package/dist/meshEdgeProjection.js.map +1 -0
  50. package/dist/meshImport.d.ts.map +1 -1
  51. package/dist/meshImport.js +2 -20
  52. package/dist/meshImport.js.map +1 -1
  53. package/dist/meshMassProperties.d.ts +92 -0
  54. package/dist/meshMassProperties.d.ts.map +1 -0
  55. package/dist/meshMassProperties.js +570 -0
  56. package/dist/meshMassProperties.js.map +1 -0
  57. package/dist/meshSection.d.ts +44 -0
  58. package/dist/meshSection.d.ts.map +1 -0
  59. package/dist/meshSection.js +154 -0
  60. package/dist/meshSection.js.map +1 -0
  61. package/dist/meshShellOverlap.d.ts +75 -0
  62. package/dist/meshShellOverlap.d.ts.map +1 -0
  63. package/dist/meshShellOverlap.js +797 -0
  64. package/dist/meshShellOverlap.js.map +1 -0
  65. package/dist/meshShellSolids.d.ts +44 -0
  66. package/dist/meshShellSolids.d.ts.map +1 -0
  67. package/dist/meshShellSolids.js +116 -0
  68. package/dist/meshShellSolids.js.map +1 -0
  69. package/dist/nodeSvgDomParser.d.ts +3 -0
  70. package/dist/nodeSvgDomParser.d.ts.map +1 -0
  71. package/dist/nodeSvgDomParser.js +53 -0
  72. package/dist/nodeSvgDomParser.js.map +1 -0
  73. package/dist/parametricRecompute.d.ts.map +1 -1
  74. package/dist/parametricRecompute.js +63 -10
  75. package/dist/parametricRecompute.js.map +1 -1
  76. package/dist/placementWorkplane.d.ts.map +1 -1
  77. package/dist/placementWorkplane.js.map +1 -1
  78. package/dist/projectAssets.d.ts +1 -1
  79. package/dist/projectStore.d.ts +1 -1
  80. package/dist/projectStore.d.ts.map +1 -1
  81. package/dist/projectStore.js +23 -2
  82. package/dist/projectStore.js.map +1 -1
  83. package/dist/revolveRequests.d.ts +57 -1
  84. package/dist/revolveRequests.d.ts.map +1 -1
  85. package/dist/revolveRequests.js +103 -4
  86. package/dist/revolveRequests.js.map +1 -1
  87. package/dist/sceneExport.d.ts +6 -0
  88. package/dist/sceneExport.d.ts.map +1 -1
  89. package/dist/sceneExport.js +6 -2
  90. package/dist/sceneExport.js.map +1 -1
  91. package/dist/serverCadInterference.d.ts +8 -45
  92. package/dist/serverCadInterference.d.ts.map +1 -1
  93. package/dist/serverCadInterference.js +21 -43
  94. package/dist/serverCadInterference.js.map +1 -1
  95. package/dist/serverCadOperations.d.ts +73 -4
  96. package/dist/serverCadOperations.d.ts.map +1 -1
  97. package/dist/serverCadOperations.js +356 -71
  98. package/dist/serverCadOperations.js.map +1 -1
  99. package/dist/serverCadProjection.d.ts +14 -1
  100. package/dist/serverCadProjection.d.ts.map +1 -1
  101. package/dist/serverCadProjection.js +135 -13
  102. package/dist/serverCadProjection.js.map +1 -1
  103. package/dist/serverCadProperties.d.ts +14 -7
  104. package/dist/serverCadProperties.d.ts.map +1 -1
  105. package/dist/serverCadProperties.js +60 -24
  106. package/dist/serverCadProperties.js.map +1 -1
  107. package/dist/serverCadSection.d.ts +21 -1
  108. package/dist/serverCadSection.d.ts.map +1 -1
  109. package/dist/serverCadSection.js +157 -43
  110. package/dist/serverCadSection.js.map +1 -1
  111. package/dist/serverCadShell.d.ts +7 -94
  112. package/dist/serverCadShell.d.ts.map +1 -1
  113. package/dist/serverCadShell.js +25 -272
  114. package/dist/serverCadShell.js.map +1 -1
  115. package/dist/serverCadThickness.d.ts +8 -8
  116. package/dist/serverCadThickness.d.ts.map +1 -1
  117. package/dist/serverCadThickness.js +15 -42
  118. package/dist/serverCadThickness.js.map +1 -1
  119. package/dist/serverShapeBooleans.d.ts +75 -0
  120. package/dist/serverShapeBooleans.d.ts.map +1 -1
  121. package/dist/serverShapeBooleans.js +251 -9
  122. package/dist/serverShapeBooleans.js.map +1 -1
  123. package/dist/serverShapeGroups.js.map +1 -1
  124. package/dist/serverStepExplode.d.ts +1 -2
  125. package/dist/serverStepExplode.d.ts.map +1 -1
  126. package/dist/serverStepExplode.js +15 -148
  127. package/dist/serverStepExplode.js.map +1 -1
  128. package/dist/shapeBounds.d.ts.map +1 -1
  129. package/dist/shapeCatalog.d.ts.map +1 -1
  130. package/dist/shapeCatalog.js +1 -0
  131. package/dist/shapeCatalog.js.map +1 -1
  132. package/dist/shapeRequests.d.ts +13 -0
  133. package/dist/shapeRequests.d.ts.map +1 -1
  134. package/dist/shapeRequests.js +14 -0
  135. package/dist/shapeRequests.js.map +1 -1
  136. package/dist/sketchCadProfile.d.ts +13 -0
  137. package/dist/sketchCadProfile.d.ts.map +1 -1
  138. package/dist/sketchCadProfile.js +108 -0
  139. package/dist/sketchCadProfile.js.map +1 -1
  140. package/dist/sketchCadSweep.js.map +1 -1
  141. package/dist/sketchEdgeSegmentLineage.d.ts +32 -0
  142. package/dist/sketchEdgeSegmentLineage.d.ts.map +1 -0
  143. package/dist/sketchEdgeSegmentLineage.js +49 -0
  144. package/dist/sketchEdgeSegmentLineage.js.map +1 -0
  145. package/dist/sketchEdgeSegmentLineageKernel.d.ts +83 -0
  146. package/dist/sketchEdgeSegmentLineageKernel.d.ts.map +1 -0
  147. package/dist/sketchEdgeSegmentLineageKernel.js +125 -0
  148. package/dist/sketchEdgeSegmentLineageKernel.js.map +1 -0
  149. package/dist/sketchFaceDraftKernel.d.ts +16 -9
  150. package/dist/sketchFaceDraftKernel.d.ts.map +1 -1
  151. package/dist/sketchFaceDraftKernel.js +19 -11
  152. package/dist/sketchFaceDraftKernel.js.map +1 -1
  153. package/dist/sketchRevolve.d.ts +13 -0
  154. package/dist/sketchRevolve.d.ts.map +1 -1
  155. package/dist/sketchRevolve.js +4 -1
  156. package/dist/sketchRevolve.js.map +1 -1
  157. package/dist/skfProject.d.ts +1 -1
  158. package/dist/skfProject.d.ts.map +1 -1
  159. package/dist/skfProject.js +63 -4
  160. package/dist/skfProject.js.map +1 -1
  161. package/dist/sphereTessellation.d.ts.map +1 -1
  162. package/dist/stepAssemblyExplode.d.ts +45 -0
  163. package/dist/stepAssemblyExplode.d.ts.map +1 -0
  164. package/dist/stepAssemblyExplode.js +195 -0
  165. package/dist/stepAssemblyExplode.js.map +1 -0
  166. package/dist/stepAssemblyHierarchy.js.map +1 -1
  167. package/dist/stepComponentMetadata.d.ts +1 -1
  168. package/dist/stepComponentMetadata.d.ts.map +1 -1
  169. package/dist/stepComponentMetadata.js +93 -39
  170. package/dist/stepComponentMetadata.js.map +1 -1
  171. package/dist/stepExport.d.ts +14 -1
  172. package/dist/stepExport.d.ts.map +1 -1
  173. package/dist/stepExport.js +81 -32
  174. package/dist/stepExport.js.map +1 -1
  175. package/dist/stepImportCommon.d.ts +4 -1
  176. package/dist/stepImportCommon.d.ts.map +1 -1
  177. package/dist/stepImportCommon.js +7 -6
  178. package/dist/stepImportCommon.js.map +1 -1
  179. package/dist/stlImport.js.map +1 -1
  180. package/dist/support/cadModifierTypes.d.ts +100 -1
  181. package/dist/support/cadModifierTypes.d.ts.map +1 -1
  182. package/dist/support/i18n/LocalizedError.d.ts.map +1 -1
  183. package/dist/support/i18n/locales/en/messages.json +42 -2
  184. package/dist/support/i18n/locales.d.ts.map +1 -1
  185. package/dist/support/lib/appTheme.d.ts.map +1 -1
  186. package/dist/support/lib/materialPresets.js.map +1 -1
  187. package/dist/support/lib/measurementUnits.d.ts.map +1 -1
  188. package/dist/support/lib/operator-configuration.json +13 -1
  189. package/dist/support/lib/operatorConfiguration.d.ts +5 -5
  190. package/dist/support/lib/workplaneGrid.js.map +1 -1
  191. package/dist/svgImport.d.ts +2 -0
  192. package/dist/svgImport.d.ts.map +1 -1
  193. package/dist/svgImport.js +7 -0
  194. package/dist/svgImport.js.map +1 -1
  195. package/dist/threadCatalog.js.map +1 -1
  196. package/dist/workplaneSettings.js.map +1 -1
  197. package/dist/workplaneShapes.d.ts +2 -2
  198. package/dist/workplaneShapes.d.ts.map +1 -1
  199. package/dist/workplaneShapes.js.map +1 -1
  200. package/package.json +7 -6
@@ -1,294 +1,45 @@
1
1
  /**
2
2
  * Hollowing a solid on the server, with a wall of a given thickness.
3
3
  *
4
- * This is the operation a 3D print needs most and the editor has never had: a
5
- * solid box weighs 8 grams of filament and a 2 mm-walled one weighs two, and a
6
- * box with its top face left open is a tray. OCCT does it with
7
- * `BRepOffsetAPI_MakeThickSolid`, which the bundled kernel exposes as `shell`.
4
+ * This is the operation a 3D print needs most: a solid box weighs 8 grams of
5
+ * filament and a 2 mm-walled one weighs two, and a box with its top face left
6
+ * open is a tray. The hollowing itself is `cadShell.ts`, which the editor's
7
+ * CAD worker shares; this module is the Node side of it.
8
8
  *
9
9
  * Node-only, and built on the same footing as the fillet endpoint: the shape is
10
10
  * rebuilt as true geometry rather than meshed, and the result is stored with
11
11
  * its exact BREP alongside the triangles, so a hollowed part still exports to
12
12
  * STEP and can still be filleted afterwards.
13
- *
14
- * Two things about `shell` are worth knowing before changing any of this, both
15
- * found by measuring rather than by reading:
16
- *
17
- * - With no faces removed it does not hollow anything. It returns the *inner*
18
- * solid -- the original offset inwards by the thickness -- so a sealed
19
- * hollow has to be the original cut by that, which is what `hollowedSolid`
20
- * does. Asking it to hollow a closed solid directly gives you back a
21
- * smaller solid part, which looks plausible and is not what was asked for.
22
- * - A thickness that does not fit does not reliably fail. Past half the
23
- * part it variously returns an empty compound, a solid that reports
24
- * `isValid: false` with a correct bounding box, or the original solid
25
- * untouched with every extent and the validity flag intact. Only the volume
26
- * tells those apart from a real answer, which is why `hollowedSolid`
27
- * measures it rather than trusting the call to throw.
28
13
  */
29
14
  import { withCadKernel } from "./serverCadKernel.js";
30
15
  import { exactPlainSketchRevolveSolid, isPlainFullTurnSketchRevolve, meshedCadResult, orientedSolidForShape, ServerCadError } from "./serverCadOperations.js";
31
- /**
32
- * The precision OCCT reconstructs the thick solid at.
33
- *
34
- * `1e-6` is the kernel's own recommendation for a precise shell and matches
35
- * what brepjs uses; the looser `1e-3` survives more inputs but produces
36
- * different topology, which would make a shelled part disagree with the same
37
- * part shelled in the editor's worker later.
38
- */
39
- const SHELL_TOLERANCE = 1e-6;
40
- /** How closely a face's normal must line up with an axis to be named for it. */
41
- const AXIS_TOLERANCE = 1e-3;
42
- /**
43
- * Names for the faces a request is likely to want open, by where they point.
44
- *
45
- * A caller that knows the geometry can name face indexes from the listing, but
46
- * nobody wants to list a box's faces to find out which one is the lid. The
47
- * local frame these resolve in is the one every geometry builder here produces:
48
- * centred in X and Z, base at Y=0, +Z towards the viewer.
49
- */
50
- const FACE_DIRECTIONS = {
51
- top: { x: 0, y: 1, z: 0 },
52
- bottom: { x: 0, y: -1, z: 0 },
53
- right: { x: 1, y: 0, z: 0 },
54
- left: { x: -1, y: 0, z: 0 },
55
- front: { x: 0, y: 0, z: 1 },
56
- back: { x: 0, y: 0, z: -1 },
57
- };
58
- export const FACE_DIRECTION_NAMES = Object.keys(FACE_DIRECTIONS);
59
- /**
60
- * The normal pointing out of the solid at the middle of a face.
61
- *
62
- * Exported because the measurement endpoint needs the same normal to answer
63
- * "what is the angle between these two faces", and a second copy of this would
64
- * be free to drift from the one the face listing and the shell request agree on.
65
- */
66
- export function faceOutwardNormal(cad, face) {
67
- try {
68
- const bounds = cad.uvBounds(face);
69
- // `surfaceNormal` already accounts for the face's own orientation, so a
70
- // reversed face reports the normal pointing out of the solid rather than
71
- // the surface's natural one. Verified against a box's six faces and
72
- // against the inner faces of a hollow, where the two disagree.
73
- const normal = cad.surfaceNormal(face, (bounds.uMin + bounds.uMax) / 2, (bounds.vMin + bounds.vMax) / 2);
74
- if (![normal.x, normal.y, normal.z].every(Number.isFinite))
75
- return null;
76
- return normal;
77
- }
78
- catch {
79
- return null;
80
- }
81
- }
82
- function axisOf(normal) {
83
- if (!normal)
84
- return null;
85
- for (const name of FACE_DIRECTION_NAMES) {
86
- const direction = FACE_DIRECTIONS[name];
87
- const dot = normal.x * direction.x + normal.y * direction.y + normal.z * direction.z;
88
- if (dot > 1 - AXIS_TOLERANCE)
89
- return name;
90
- }
91
- return null;
92
- }
93
- /** How far out along its own direction a face sits, which is what settles a tie. */
94
- function reachAlong(centroid, direction) {
95
- return centroid.x * direction.x + centroid.y * direction.y + centroid.z * direction.z;
96
- }
16
+ import { CadShellError, describeShellFaces, shellSolid } from "./cadShell.js";
17
+ export { FACE_DIRECTION_NAMES, faceOutwardNormal } from "./cadShell.js";
97
18
  function faceSummaries(cad, solid, shape, preferStoredIds = true) {
98
- const faces = cad.getSubShapes(solid, "face");
99
- const storedIds = preferStoredIds && shape.faceIds?.length === faces.length ? shape.faceIds : undefined;
100
- const described = faces.map((handle, index) => {
101
- const normal = faceOutwardNormal(cad, handle);
102
- let surfaceType = "unknown";
103
- try {
104
- surfaceType = cad.surfaceType(handle);
105
- }
106
- catch {
107
- // Not every surface reports a type; the area and centroid still do.
108
- }
109
- const centroid = cad.getSurfaceCenterOfMass(handle);
110
- return {
111
- index,
112
- id: storedIds?.[index] ?? `face_${encodeURIComponent(shape.id)}_${index}`,
113
- surfaceType,
114
- area: cad.getSurfaceArea(handle),
115
- centroid: { x: centroid.x, y: centroid.y, z: centroid.z },
116
- normal: normal ? { x: normal.x, y: normal.y, z: normal.z } : null,
117
- // A flat face is the only kind a direction name can mean: "the top" of a
118
- // sphere is a point on a curved surface, not a lid you can take off.
119
- axis: surfaceType === "plane" ? axisOf(normal) : null,
120
- };
121
- });
122
- // Several faces can point the same way -- the lid of a hollow box and the
123
- // floor of its cavity both point up -- so a name belongs to the outermost of
124
- // them. Without this, opening "top" on an already-hollow part would pick the
125
- // cavity floor and quietly produce nonsense.
126
- const furthest = new Map();
127
- for (const face of described) {
128
- if (!face.axis)
129
- continue;
130
- const reach = reachAlong(face.centroid, FACE_DIRECTIONS[face.axis]);
131
- const best = furthest.get(face.axis);
132
- if (best === undefined || reach > best)
133
- furthest.set(face.axis, reach);
134
- }
135
- return described.map(({ axis, ...face }) => ({
136
- ...face,
137
- facing: axis && Math.abs(reachAlong(face.centroid, FACE_DIRECTIONS[axis]) - (furthest.get(axis) ?? 0)) < AXIS_TOLERANCE
138
- ? axis
139
- : null,
19
+ const described = describeShellFaces(cad, solid);
20
+ const storedIds = preferStoredIds && shape.faceIds?.length === described.length ? shape.faceIds : undefined;
21
+ return described.map((face) => ({
22
+ index: face.index,
23
+ id: storedIds?.[face.index] ?? `face_${encodeURIComponent(shape.id)}_${face.index}`,
24
+ surfaceType: face.surfaceType,
25
+ area: face.area,
26
+ centroid: face.centroid,
27
+ normal: face.normal,
28
+ facing: face.facing,
140
29
  }));
141
30
  }
142
31
  /** A shape's faces, numbered as a shell request refers to them by index. */
143
32
  export function shapeFaces(shape, options = {}) {
144
33
  return withCadKernel((cad) => {
145
34
  if (options.topology === "exact" && isPlainFullTurnSketchRevolve(shape)) {
146
- if (shape.faceColors && Object.keys(shape.faceColors).length > 0) {
147
- throw new ServerCadError("Exact revolve face listing is unavailable while legacy face colors are stored.");
148
- }
149
35
  const exact = exactPlainSketchRevolveSolid(cad, shape.sketchProfile, shape.sketchRevolve, shape);
150
36
  return faceSummaries(cad, exact, shape, false);
151
37
  }
152
38
  return faceSummaries(cad, orientedSolidForShape(cad, shape), shape);
153
39
  });
154
40
  }
155
- /**
156
- * The face indexes a request's `openFaces` names, in listing order.
157
- *
158
- * Mixed on purpose: `["top"]` is what a script asking for a tray wants to write,
159
- * and an index from the listing is the only way to name a face that no direction
160
- * describes -- one wall of a hexagonal pot, say.
161
- */
162
- function resolveOpenFaces(requested, faces) {
163
- const chosen = new Set();
164
- for (const entry of requested) {
165
- if (typeof entry === "number") {
166
- if (!Number.isInteger(entry) || entry < 0 || entry >= faces.length) {
167
- throw new ServerCadError(`Face indexes must be between 0 and ${faces.length - 1}.`, 400);
168
- }
169
- chosen.add(entry);
170
- continue;
171
- }
172
- const name = entry.trim().toLowerCase();
173
- if (!FACE_DIRECTION_NAMES.includes(name)) {
174
- throw new ServerCadError(`"${entry}" is not a face direction. Use one of ${FACE_DIRECTION_NAMES.join(", ")}, or a face index from the face listing.`, 400);
175
- }
176
- const matched = faces.filter((face) => face.facing === name);
177
- if (matched.length === 0) {
178
- throw new ServerCadError(`This shape has no flat ${name} face to open. Name a face index from the face listing instead.`, 422);
179
- }
180
- for (const face of matched)
181
- chosen.add(face.index);
182
- }
183
- return [...chosen].sort((left, right) => left - right);
184
- }
185
- /** The single solid inside whatever OCCT handed back, or the shape itself. */
186
- function soleSolid(cad, result) {
187
- const solids = cad.getSubShapes(result, "solid");
188
- return solids.length === 1 ? solids[0] : result;
189
- }
190
- function volumeOf(cad, shape) {
191
- try {
192
- const volume = cad.getVolume(shape);
193
- return Number.isFinite(volume) ? volume : null;
194
- }
195
- catch {
196
- return null;
197
- }
198
- }
199
- const TOO_THICK = "That wall thickness is too large for this shape: hollowing it at that thickness leaves no cavity. Try a thinner wall.";
200
- /**
201
- * What OCCT refusing outright actually means, as far as it can be told apart.
202
- *
203
- * A thickness that merely does not fit does not throw: it comes back as an
204
- * empty compound, a solid that fails its own validity check, or the original
205
- * untouched, all of which `hollowedSolid` catches by measuring. A throw is the
206
- * other failure, and it tracks the *kind of surface* rather than the number.
207
- *
208
- * It is not "curved": an analytic sphere, cylinder, cone and torus all offset
209
- * perfectly well. What fails is a **spline** skin -- OCCT will not offset one
210
- * inwards at any thickness or at any reconstruction tolerance (checked at 1e-6,
211
- * 1e-4, 1e-3 and 1e-2). In this app that is an elliptical ball, a loft, and
212
- * anything built by extruding a profile wire, because those surfaces are
213
- * splines however round they look.
214
- */
215
- const CANNOT_OFFSET = "OCCT could not hollow this shape: its surfaces cannot be offset inwards into a sound solid. A shape whose skin is a spline rather than an analytic surface -- a ball with unequal radii, a loft -- fails this way at any wall thickness, however round it looks.";
216
41
  /** What a result OCCT built but cannot write out means, which is nothing good. */
217
42
  const UNREADABLE = "The hollowed solid came out of OCCT in a state it cannot read back, so it has not been stored. Try a different wall thickness.";
218
- /** Whether a handle is a solid OCCT itself will vouch for. */
219
- function isSoundSolid(cad, shape) {
220
- try {
221
- return cad.isSolid(shape) && Boolean(cad.isValid(shape));
222
- }
223
- catch {
224
- // An empty compound throws from `isValid` rather than reporting false.
225
- return false;
226
- }
227
- }
228
- /**
229
- * The hollowed solid, or a refusal.
230
- *
231
- * Both paths run through OCCT's thick-solid builder, which answers two
232
- * different questions depending on whether any face is removed -- see the
233
- * module note. The checks around it are not belt and braces: every one of them
234
- * has a real input that reaches it, and the order matters, because it is what
235
- * separates a wall that does not fit from a shape that cannot be hollowed at
236
- * all. The inward offset is measured before it is cut away, so a thickness
237
- * that collapses it is reported as a thickness rather than blamed on the
238
- * shape's surfaces.
239
- */
240
- function hollowedSolid(cad, solid, thickness, openFaces) {
241
- const sourceVolume = volumeOf(cad, solid);
242
- if (sourceVolume === null || sourceVolume <= 0) {
243
- throw new ServerCadError("That shape has no volume to hollow out.");
244
- }
245
- let hollow;
246
- if (openFaces.length > 0) {
247
- const faces = cad.getSubShapes(solid, "face");
248
- try {
249
- hollow = cad.shell(solid, openFaces.map((index) => faces[index]), thickness, SHELL_TOLERANCE);
250
- }
251
- catch {
252
- throw new ServerCadError(CANNOT_OFFSET);
253
- }
254
- }
255
- else {
256
- // No face removed: `shell` returns the inward offset solid rather than a
257
- // hollow, so the sealed void is the original cut by it.
258
- let inner;
259
- try {
260
- inner = cad.shell(solid, [], thickness, SHELL_TOLERANCE);
261
- }
262
- catch {
263
- throw new ServerCadError(CANNOT_OFFSET);
264
- }
265
- // The cavity, before it is a cavity. Past half the part this is an empty
266
- // compound, and cutting the solid by it throws -- which would otherwise
267
- // read as the shape's fault rather than the thickness's.
268
- const innerVolume = volumeOf(cad, inner);
269
- if (!isSoundSolid(cad, inner) || innerVolume === null || innerVolume <= 0 || innerVolume >= sourceVolume) {
270
- throw new ServerCadError(TOO_THICK);
271
- }
272
- try {
273
- hollow = cad.cut(solid, inner);
274
- }
275
- catch {
276
- throw new ServerCadError(CANNOT_OFFSET);
277
- }
278
- }
279
- const result = soleSolid(cad, hollow);
280
- if (!isSoundSolid(cad, result))
281
- throw new ServerCadError(TOO_THICK);
282
- const volume = volumeOf(cad, result);
283
- if (volume === null || volume <= 0)
284
- throw new ServerCadError(TOO_THICK);
285
- // Past the thickness that fits, OCCT hands back the original solid with
286
- // every extent and the validity flag intact. Hollowing always removes the
287
- // cavity, so a result that weighs what it started at did nothing.
288
- if (volume >= sourceVolume * (1 - 1e-6))
289
- throw new ServerCadError(TOO_THICK);
290
- return result;
291
- }
292
43
  /**
293
44
  * Hollow a shape out and return the exact result with a mesh of it.
294
45
  *
@@ -301,14 +52,16 @@ export function applyShell(shape, request) {
301
52
  }
302
53
  return withCadKernel((cad) => {
303
54
  const solid = orientedSolidForShape(cad, shape);
304
- const faces = faceSummaries(cad, solid, shape);
305
- if (faces.length === 0)
306
- throw new ServerCadError("That shape has no faces to hollow out.");
307
- const openFaces = resolveOpenFaces(request.openFaces ?? [], faces);
308
- if (openFaces.length === faces.length) {
309
- throw new ServerCadError("Leaving every face open would remove the shape rather than hollow it. Leave at least one face closed.");
55
+ let hollow;
56
+ try {
57
+ hollow = shellSolid(cad, solid, request).solid;
58
+ }
59
+ catch (error) {
60
+ // The same refusal, said the way the REST API says it.
61
+ if (error instanceof CadShellError)
62
+ throw new ServerCadError(error.message, error.status);
63
+ throw error;
310
64
  }
311
- const hollow = hollowedSolid(cad, solid, request.thickness, openFaces);
312
65
  try {
313
66
  return meshedCadResult(cad, hollow, shape);
314
67
  }
@@ -1 +1 @@
1
- {"version":3,"file":"serverCadShell.js","sourceRoot":"","sources":["../src/serverCadShell.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serverCadShell.js","sourceRoot":"","sources":["../src/serverCadShell.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
- /** Sampled wall-thickness analysis for exact project solids. Node-only. */
1
+ /**
2
+ * Sampled wall-thickness analysis for exact project solids. Node-only.
3
+ *
4
+ * The sampling lives in `cadAnalysis`, which the editor's CAD worker shares;
5
+ * this places the stored shape and runs it on the server's kernel.
6
+ */
7
+ import { type WallThicknessResult } from "./cadAnalysis.js";
2
8
  import type { WorkplaneShape } from "./domain/sketchforge.js";
3
- export type WallThicknessResult = {
4
- minimum: number | null;
5
- unit: "mm";
6
- method: "sampled-opposing-surface-distance";
7
- samplesPerFace: number;
8
- facesChecked: number;
9
- };
9
+ export type { WallThicknessResult } from "./cadAnalysis.js";
10
10
  /**
11
11
  * Return the smallest sampled distance between opposing faces. This is a
12
12
  * screening estimate, not a medial-axis or certified minimum-thickness result.
@@ -1 +1 @@
1
- {"version":3,"file":"serverCadThickness.d.ts","sourceRoot":"","sources":["../src/serverCadThickness.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAM3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAK9D,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,mCAAmC,CAAC;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAeF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuBjF"}
1
+ {"version":3,"file":"serverCadThickness.d.ts","sourceRoot":"","sources":["../src/serverCadThickness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAA8C,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,CASjF"}
@@ -1,54 +1,27 @@
1
- /** Sampled wall-thickness analysis for exact project solids. Node-only. */
1
+ /**
2
+ * Sampled wall-thickness analysis for exact project solids. Node-only.
3
+ *
4
+ * The sampling lives in `cadAnalysis`, which the editor's CAD worker shares;
5
+ * this places the stored shape and runs it on the server's kernel.
6
+ */
2
7
  import { withCadKernel } from "./serverCadKernel.js";
3
8
  import { ServerCadError } from "./serverCadOperations.js";
4
9
  import { placedSolidForShape } from "./serverShapeBooleans.js";
5
- const MAX_FACES = 256;
6
- const GRID = 5;
7
- function samples(cad, face) {
8
- const uv = cad.uvBounds(face);
9
- const points = [];
10
- for (let i = 0; i < GRID; i += 1)
11
- for (let j = 0; j < GRID; j += 1) {
12
- const u = uv.uMin + (uv.uMax - uv.uMin) * (i + 0.5) / GRID;
13
- const v = uv.vMin + (uv.vMax - uv.vMin) * (j + 0.5) / GRID;
14
- if (cad.classifyPointOnFace(face, u, v) !== "out") {
15
- points.push({ point: cad.pointOnSurface(face, u, v), normal: cad.surfaceNormal(face, u, v) });
16
- }
17
- }
18
- return points;
19
- }
10
+ import { sampledWallThickness, WallThicknessRefusal } from "./cadAnalysis.js";
20
11
  /**
21
12
  * Return the smallest sampled distance between opposing faces. This is a
22
13
  * screening estimate, not a medial-axis or certified minimum-thickness result.
23
14
  */
24
15
  export function wallThickness(shape) {
25
16
  return withCadKernel((cad) => {
26
- const solid = placedSolidForShape(cad, shape);
27
- const faces = cad.getSubShapes(solid, "face");
28
- if (!faces.length)
29
- throw new ServerCadError("The shape has no faces to analyze.");
30
- if (faces.length > MAX_FACES)
31
- throw new ServerCadError(`Wall-thickness analysis supports at most ${MAX_FACES} faces.`, 413);
32
- const sampled = faces.map((face) => samples(cad, face));
33
- let minimum = Infinity;
34
- for (let i = 0; i < faces.length; i += 1)
35
- for (let j = i + 1; j < faces.length; j += 1) {
36
- for (const source of sampled[i]) {
37
- for (const target of sampled[j]) {
38
- const dot = source.normal.x * target.normal.x + source.normal.y * target.normal.y + source.normal.z * target.normal.z;
39
- if (dot > -0.5)
40
- continue;
41
- const uv = cad.uvFromPoint(faces[j], source.point);
42
- if (cad.classifyPointOnFace(faces[j], uv.u, uv.v) === "out")
43
- continue;
44
- const projected = cad.pointOnSurface(faces[j], uv.u, uv.v);
45
- const distance = Math.hypot(source.point.x - projected.x, source.point.y - projected.y, source.point.z - projected.z);
46
- if (distance > 1e-7 && distance < minimum)
47
- minimum = distance;
48
- }
49
- }
50
- }
51
- return { minimum: Number.isFinite(minimum) ? minimum : null, unit: "mm", method: "sampled-opposing-surface-distance", samplesPerFace: GRID * GRID, facesChecked: faces.length };
17
+ try {
18
+ return sampledWallThickness(cad, placedSolidForShape(cad, shape));
19
+ }
20
+ catch (error) {
21
+ if (error instanceof WallThicknessRefusal)
22
+ throw new ServerCadError(error.message, error.reason === "too_many_faces" ? 413 : 422);
23
+ throw error;
24
+ }
52
25
  });
53
26
  }
54
27
  //# sourceMappingURL=serverCadThickness.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serverCadThickness.js","sourceRoot":"","sources":["../src/serverCadThickness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serverCadThickness.js","sourceRoot":"","sources":["../src/serverCadThickness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAA4B,MAAM,kBAAkB,CAAC;AAKxG;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,OAAO,aAAa,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,OAAO,oBAAoB,CAAC,GAAG,EAAE,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,oBAAoB;gBAAE,MAAM,IAAI,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAClI,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -54,6 +54,81 @@ export type GroupBuildOutcome = {
54
54
  * `generalTransform` because a reflection is not a rigid placement.
55
55
  */
56
56
  export declare function placedSolidForShape(cad: OcctKernel, shape: WorkplaneShape): ShapeHandle;
57
+ /** Which stored representation supplied the geometry, and whether it is exact. */
58
+ export type ShapeGeometryProvenance = {
59
+ /** Which stored representation supplied the geometry that was measured. */
60
+ source: "parametric" | "brep" | "mesh";
61
+ /** Imported triangle meshes remain tessellated even after sewing into a solid. */
62
+ precision: "exact" | "tessellated";
63
+ };
64
+ export type PlacedSolid = {
65
+ solid: ShapeHandle;
66
+ provenance: ShapeGeometryProvenance;
67
+ };
68
+ /**
69
+ * The shape as a placed solid, together with the representation it was
70
+ * actually built from. Reported by the builder rather than guessed from the
71
+ * shape's fields beforehand, because only building it can tell whether a
72
+ * stored B-rep passed its check or a group member fell back to its mesh.
73
+ */
74
+ export declare function placedSolid(cad: OcctKernel, shape: WorkplaneShape): PlacedSolid;
75
+ /**
76
+ * Whether the shape is a boolean result whose stored B-rep is still the exact
77
+ * form of the mesh it is drawn with (#541).
78
+ *
79
+ * A cut stores two descriptions of one solid: the triangles the viewport
80
+ * draws, and the B-rep they were tessellated from, both in the result's own
81
+ * frame -- centred in X and Z, base at Y = 0. While the two agree, the B-rep is
82
+ * the better answer to "what is this solid", so measurement, interference and
83
+ * a further boolean read it instead of sewing the triangles back up.
84
+ *
85
+ * They stop agreeing when an edit reaches the mesh and not the B-rep. Moving,
86
+ * turning and mirroring do not: they are placement, applied to both alike. A
87
+ * resize does, because it stretches the stored triangles and the B-rep keeps
88
+ * its original size; so does a taper, and so does a frame recorded with a
89
+ * baked `sourceTransform`, which puts the B-rep somewhere other than the
90
+ * mesh's frame. A result made from a mesh operand is left out too: its B-rep
91
+ * was sewn from triangles, so calling it exact would be a claim about
92
+ * geometry nobody ever had.
93
+ *
94
+ * Edge treatments, drafts and shells rewrite the B-rep under their own rules
95
+ * and stay on the paths they had.
96
+ */
97
+ export declare function hasCurrentResultBrep(shape: WorkplaneShape): boolean;
98
+ /**
99
+ * A boolean result's stored B-rep, placed where the shape stands, or null to
100
+ * use its mesh instead.
101
+ *
102
+ * Placed the way the mesh is placed, since the two share a frame: mirrored
103
+ * exactly about the shape's centre, then moved rigidly, so the cut's
104
+ * cylinders stay cylinders. A cut's B-rep is in the result's own frame, at the
105
+ * origin -- what `cadBrepFrame` records for a cut since #548, and what loading
106
+ * a project corrects an older cut's frame to (`migratePre548CutBrepFrames`) --
107
+ * so the frame's position is not needed here; `cadBrepTransformForShape` would
108
+ * give the same placement, only with the mirror folded into an affine scale.
109
+ * A B-rep stored anywhere else fails the bounds check below and falls back to
110
+ * the mesh.
111
+ *
112
+ * The B-rep is checked against the mesh before it is trusted, because the
113
+ * structural test cannot see an edit that replaced the triangles and left the
114
+ * B-rep behind. The triangles' corners lie on the true surfaces, so the two
115
+ * boxes agree to within the meshing tolerance; a B-rep that misses by more is
116
+ * describing something else, and the mesh is what is on screen.
117
+ */
118
+ export declare function placedResultBrepSolid(cad: OcctKernel, shape: WorkplaneShape): ShapeHandle | null;
119
+ /**
120
+ * A plain revolve's exact solid where it stands, as BREP text, or null for any
121
+ * other shape: what the STEP exporter writes for a revolve instead of skipping
122
+ * it as a mesh with no B-rep source (#523).
123
+ */
124
+ export declare function placedExactRevolveBrep(shape: WorkplaneShape): Promise<string | null>;
125
+ /**
126
+ * Whether the shape is a group held only as a record of its children.
127
+ *
128
+ * Grouping solids with no hole among them stores the children and nothing
129
+ * else, in the editor and here alike, so there is no mesh or BREP to read.
130
+ */
131
+ export declare function isGroupRecord(shape: WorkplaneShape): boolean;
57
132
  /**
58
133
  * A group holding the given shapes, with any hole among them cut out.
59
134
  *
@@ -1 +1 @@
1
- {"version":3,"file":"serverShapeBooleans.d.ts","sourceRoot":"","sources":["../src/serverShapeBooleans.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAezD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,MAAM,iBAAiB,GACzB;IACA,KAAK,EAAE,cAAc,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GACC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuBtC;;;;;;;;GAQG;AACH;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,GAAG,WAAW,CAiBvF;AAoCD;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAyErG"}
1
+ {"version":3,"file":"serverShapeBooleans.d.ts","sourceRoot":"","sources":["../src/serverShapeBooleans.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAkBzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,MAAM,MAAM,iBAAiB,GACzB;IACA,KAAK,EAAE,cAAc,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GACC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAuBtC;;;;;;;;GAQG;AACH;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,GAAG,WAAW,CAEvF;AAED,kFAAkF;AAClF,MAAM,MAAM,uBAAuB,GAAG;IACpC,2EAA2E;IAC3E,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;IACvC,kFAAkF;IAClF,SAAS,EAAE,OAAO,GAAG,aAAa,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,UAAU,EAAE,uBAAuB,CAAA;CAAE,CAAC;AAkBtF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,GAAG,WAAW,CAuB/E;AAkBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAUnE;AA8CD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,GAAG,WAAW,GAAG,IAAI,CA6BhG;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGpF;AAQD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,WAElD;AAuED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA6ErG"}