fluidcad 0.0.36 → 0.0.37

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 (178) hide show
  1. package/LICENSE.txt +21 -504
  2. package/README.md +1 -1
  3. package/lib/dist/common/edge.d.ts +1 -1
  4. package/lib/dist/common/face.d.ts +1 -1
  5. package/lib/dist/common/scene-object.d.ts +6 -0
  6. package/lib/dist/common/scene-object.js +8 -0
  7. package/lib/dist/common/shape-factory.d.ts +1 -1
  8. package/lib/dist/common/shape-history-tracker.d.ts +1 -1
  9. package/lib/dist/common/shape.d.ts +1 -1
  10. package/lib/dist/common/solid.d.ts +1 -1
  11. package/lib/dist/common/transformable-primitive.d.ts +12 -1
  12. package/lib/dist/common/transformable-primitive.js +27 -0
  13. package/lib/dist/common/vertex.d.ts +1 -1
  14. package/lib/dist/common/wire.d.ts +1 -1
  15. package/lib/dist/core/2d/index.d.ts +1 -0
  16. package/lib/dist/core/2d/index.js +1 -0
  17. package/lib/dist/core/2d/text.d.ts +30 -0
  18. package/lib/dist/core/2d/text.js +37 -0
  19. package/lib/dist/core/helix.d.ts +20 -0
  20. package/lib/dist/core/helix.js +36 -0
  21. package/lib/dist/core/index.d.ts +3 -1
  22. package/lib/dist/core/index.js +2 -0
  23. package/lib/dist/core/interfaces.d.ts +180 -0
  24. package/lib/dist/core/wrap.d.ts +17 -0
  25. package/lib/dist/core/wrap.js +39 -0
  26. package/lib/dist/features/2d/text.d.ts +67 -0
  27. package/lib/dist/features/2d/text.js +320 -0
  28. package/lib/dist/features/cylinder.d.ts +3 -1
  29. package/lib/dist/features/cylinder.js +5 -2
  30. package/lib/dist/features/extrude-base.d.ts +1 -0
  31. package/lib/dist/features/extrude-to-face.d.ts +1 -0
  32. package/lib/dist/features/extrude-to-face.js +6 -0
  33. package/lib/dist/features/fillet.d.ts +1 -1
  34. package/lib/dist/features/helix.d.ts +41 -0
  35. package/lib/dist/features/helix.js +337 -0
  36. package/lib/dist/features/select.js +32 -8
  37. package/lib/dist/features/simple-extruder.d.ts +1 -1
  38. package/lib/dist/features/simple-extruder.js +7 -2
  39. package/lib/dist/features/sphere.d.ts +3 -1
  40. package/lib/dist/features/sphere.js +5 -2
  41. package/lib/dist/features/sweep.js +7 -2
  42. package/lib/dist/features/wrap.d.ts +39 -0
  43. package/lib/dist/features/wrap.js +116 -0
  44. package/lib/dist/filters/edge/belongs-to-face.d.ts +3 -1
  45. package/lib/dist/filters/edge/belongs-to-face.js +14 -10
  46. package/lib/dist/filters/filter.d.ts +1 -1
  47. package/lib/dist/filters/from-object.d.ts +1 -1
  48. package/lib/dist/filters/tangent-expander.d.ts +1 -1
  49. package/lib/dist/filters/tangent-expander.js +57 -40
  50. package/lib/dist/helpers/scene-helpers.d.ts +2 -0
  51. package/lib/dist/helpers/scene-helpers.js +1 -1
  52. package/lib/dist/index.d.ts +2 -0
  53. package/lib/dist/index.js +3 -1
  54. package/lib/dist/io/file-import.d.ts +7 -0
  55. package/lib/dist/io/file-import.js +28 -1
  56. package/lib/dist/io/font-registry.d.ts +45 -0
  57. package/lib/dist/io/font-registry.js +272 -0
  58. package/lib/dist/math/bspline-interpolation.d.ts +29 -0
  59. package/lib/dist/math/bspline-interpolation.js +194 -0
  60. package/lib/dist/oc/boolean-ops.d.ts +3 -1
  61. package/lib/dist/oc/boolean-ops.js +15 -1
  62. package/lib/dist/oc/color-transfer.d.ts +1 -1
  63. package/lib/dist/oc/constraints/constraint-helpers.d.ts +4 -4
  64. package/lib/dist/oc/constraints/curve/tangent-circle-solver.js +10 -9
  65. package/lib/dist/oc/constraints/curve/tangent-line-solver.js +5 -6
  66. package/lib/dist/oc/convert.d.ts +1 -1
  67. package/lib/dist/oc/draft-ops.d.ts +1 -1
  68. package/lib/dist/oc/edge-ops.d.ts +2 -2
  69. package/lib/dist/oc/edge-ops.js +13 -14
  70. package/lib/dist/oc/edge-props.d.ts +1 -1
  71. package/lib/dist/oc/edge-query.d.ts +1 -1
  72. package/lib/dist/oc/edge-query.js +3 -8
  73. package/lib/dist/oc/errors.d.ts +8 -0
  74. package/lib/dist/oc/errors.js +27 -0
  75. package/lib/dist/oc/explorer.d.ts +2 -2
  76. package/lib/dist/oc/extrude-ops.d.ts +28 -2
  77. package/lib/dist/oc/extrude-ops.js +56 -7
  78. package/lib/dist/oc/face-ops.d.ts +2 -1
  79. package/lib/dist/oc/face-ops.js +11 -0
  80. package/lib/dist/oc/face-props.d.ts +1 -1
  81. package/lib/dist/oc/face-query.d.ts +12 -1
  82. package/lib/dist/oc/face-query.js +39 -0
  83. package/lib/dist/oc/fillet-ops.d.ts +1 -1
  84. package/lib/dist/oc/fillet-ops.js +4 -4
  85. package/lib/dist/oc/geometry.d.ts +1 -1
  86. package/lib/dist/oc/geometry.js +12 -14
  87. package/lib/dist/oc/helix-ops.d.ts +37 -0
  88. package/lib/dist/oc/helix-ops.js +88 -0
  89. package/lib/dist/oc/hit-test.d.ts +1 -1
  90. package/lib/dist/oc/index.d.ts +4 -0
  91. package/lib/dist/oc/index.js +2 -0
  92. package/lib/dist/oc/init.d.ts +1 -1
  93. package/lib/dist/oc/init.js +1 -1
  94. package/lib/dist/oc/intersection.js +1 -1
  95. package/lib/dist/oc/io.d.ts +6 -6
  96. package/lib/dist/oc/io.js +31 -24
  97. package/lib/dist/oc/measure/classify.d.ts +34 -0
  98. package/lib/dist/oc/measure/classify.js +246 -0
  99. package/lib/dist/oc/measure/measure-ops.d.ts +9 -0
  100. package/lib/dist/oc/measure/measure-ops.js +210 -0
  101. package/lib/dist/oc/measure/measure-types.d.ts +39 -0
  102. package/lib/dist/oc/measure/measure-types.js +1 -0
  103. package/lib/dist/oc/measure/sampling.d.ts +9 -0
  104. package/lib/dist/oc/measure/sampling.js +77 -0
  105. package/lib/dist/oc/measure/vec.d.ts +13 -0
  106. package/lib/dist/oc/measure/vec.js +23 -0
  107. package/lib/dist/oc/mesh.d.ts +1 -1
  108. package/lib/dist/oc/mesh.js +40 -28
  109. package/lib/dist/oc/path-sampler.d.ts +29 -0
  110. package/lib/dist/oc/path-sampler.js +63 -0
  111. package/lib/dist/oc/props.d.ts +1 -1
  112. package/lib/dist/oc/props.js +4 -1
  113. package/lib/dist/oc/shape-hash.d.ts +26 -0
  114. package/lib/dist/oc/shape-hash.js +32 -0
  115. package/lib/dist/oc/shape-ops.d.ts +5 -3
  116. package/lib/dist/oc/shape-ops.js +6 -5
  117. package/lib/dist/oc/sweep-ops.d.ts +22 -1
  118. package/lib/dist/oc/sweep-ops.js +206 -18
  119. package/lib/dist/oc/text-outline.d.ts +62 -0
  120. package/lib/dist/oc/text-outline.js +212 -0
  121. package/lib/dist/oc/topology-index.d.ts +1 -1
  122. package/lib/dist/oc/vertex-ops.d.ts +1 -1
  123. package/lib/dist/oc/wire-ops.d.ts +1 -1
  124. package/lib/dist/oc/wire-ops.js +1 -1
  125. package/lib/dist/oc/wrap-development.d.ts +105 -0
  126. package/lib/dist/oc/wrap-development.js +179 -0
  127. package/lib/dist/oc/wrap-ops.d.ts +100 -0
  128. package/lib/dist/oc/wrap-ops.js +406 -0
  129. package/lib/dist/rendering/render-solid.js +10 -2
  130. package/lib/dist/scene-manager.d.ts +2 -0
  131. package/lib/dist/scene-manager.js +29 -0
  132. package/lib/dist/tests/features/cylinder-curve-filter.test.js +3 -3
  133. package/lib/dist/tests/features/extrude-to-face.test.js +38 -1
  134. package/lib/dist/tests/features/helix.test.d.ts +1 -0
  135. package/lib/dist/tests/features/helix.test.js +295 -0
  136. package/lib/dist/tests/features/repeat-primitive.test.d.ts +1 -0
  137. package/lib/dist/tests/features/repeat-primitive.test.js +60 -0
  138. package/lib/dist/tests/features/rib.test.js +6 -1
  139. package/lib/dist/tests/features/sweep.test.js +125 -1
  140. package/lib/dist/tests/features/text.test.d.ts +1 -0
  141. package/lib/dist/tests/features/text.test.js +347 -0
  142. package/lib/dist/tests/features/wrap-development.test.d.ts +1 -0
  143. package/lib/dist/tests/features/wrap-development.test.js +130 -0
  144. package/lib/dist/tests/features/wrap-extruded-target.test.d.ts +1 -0
  145. package/lib/dist/tests/features/wrap-extruded-target.test.js +106 -0
  146. package/lib/dist/tests/features/wrap-repeat.test.d.ts +1 -0
  147. package/lib/dist/tests/features/wrap-repeat.test.js +93 -0
  148. package/lib/dist/tests/features/wrap.test.d.ts +1 -0
  149. package/lib/dist/tests/features/wrap.test.js +331 -0
  150. package/lib/dist/tests/math/bspline-interpolation.test.d.ts +1 -0
  151. package/lib/dist/tests/math/bspline-interpolation.test.js +119 -0
  152. package/lib/dist/tests/measure.test.d.ts +1 -0
  153. package/lib/dist/tests/measure.test.js +288 -0
  154. package/lib/dist/tsconfig.tsbuildinfo +1 -1
  155. package/llm-docs/api/helix.md +64 -0
  156. package/llm-docs/api/index.json +11 -2
  157. package/llm-docs/api/text.md +52 -0
  158. package/llm-docs/api/types/helix.md +105 -0
  159. package/llm-docs/api/types/text.md +138 -0
  160. package/llm-docs/api/types/wrap.md +131 -0
  161. package/llm-docs/api/wrap.md +62 -0
  162. package/llm-docs/index.json +121 -1
  163. package/mcp/dist/server.js +20 -1
  164. package/mcp/dist/tools/inspection.d.ts +17 -0
  165. package/mcp/dist/tools/inspection.js +14 -0
  166. package/package.json +7 -3
  167. package/server/dist/fluidcad-server.d.ts +10 -0
  168. package/server/dist/fluidcad-server.js +10 -0
  169. package/server/dist/index.js +4 -2
  170. package/server/dist/preferences.d.ts +4 -0
  171. package/server/dist/preferences.js +2 -0
  172. package/server/dist/routes/measure.d.ts +3 -0
  173. package/server/dist/routes/measure.js +32 -0
  174. package/server/dist/routes/preferences.js +6 -0
  175. package/server/dist/routes/sketch-edits.js +2 -1
  176. package/ui/dist/assets/{index-CDJmUpFI.css → index-dAFdg2Un.css} +1 -1
  177. package/ui/dist/assets/{index-MRqwG9Vh.js → index-no7mtr5s.js} +149 -102
  178. package/ui/dist/index.html +2 -2
@@ -0,0 +1,320 @@
1
+ import { Sketch } from "./sketch.js";
2
+ import { ExtrudableGeometryBase } from "./extrudable-base.js";
3
+ import { FontRegistry } from "../../io/font-registry.js";
4
+ import { TextOutline } from "../../oc/text-outline.js";
5
+ import { PathSampler } from "../../oc/path-sampler.js";
6
+ import { WireOps } from "../../oc/wire-ops.js";
7
+ import { BuildError } from "../../common/build-error.js";
8
+ import { GeometrySceneObject } from "./geometry.js";
9
+ import { Plane } from "../../math/plane.js";
10
+ import { Point } from "../../math/point.js";
11
+ import { Vector3d } from "../../math/vector3d.js";
12
+ const WEIGHT_NAMES = {
13
+ thin: 100, extralight: 200, ultralight: 200, light: 300, regular: 400,
14
+ normal: 400, medium: 500, semibold: 600, demibold: 600, bold: 700,
15
+ extrabold: 800, ultrabold: 800, black: 900, heavy: 900,
16
+ };
17
+ /**
18
+ * Fits a plane through sampled path points (Newell-style accumulation of
19
+ * cross products around the centroid). Returns null when the points are
20
+ * colinear — a straight path carries no orientation of its own.
21
+ */
22
+ function fitPathPlane(samples, startTangent, pathLength) {
23
+ const n = samples.length;
24
+ let cx = 0, cy = 0, cz = 0;
25
+ for (const p of samples) {
26
+ cx += p.x;
27
+ cy += p.y;
28
+ cz += p.z;
29
+ }
30
+ const centroid = new Point(cx / n, cy / n, cz / n);
31
+ let nx = 0, ny = 0, nz = 0;
32
+ for (let i = 0; i + 1 < n; i++) {
33
+ const a = centroid.vectorTo(samples[i]);
34
+ const b = centroid.vectorTo(samples[i + 1]);
35
+ const cross = a.cross(b);
36
+ nx += cross.x;
37
+ ny += cross.y;
38
+ nz += cross.z;
39
+ }
40
+ const mag = Math.hypot(nx, ny, nz);
41
+ if (mag < 1e-9 * pathLength * pathLength) {
42
+ return null;
43
+ }
44
+ const normal = new Vector3d(nx / mag, ny / mag, nz / mag);
45
+ const xDirection = startTangent
46
+ .subtract(normal.multiply(startTangent.dot(normal)))
47
+ .normalize();
48
+ return new Plane(samples[0], xDirection, normal);
49
+ }
50
+ /**
51
+ * 3D text as an extrudable outline profile. Glyph outlines are produced via
52
+ * fontkit and converted to sketch edges; extruding the result gives raised or
53
+ * cut lettering. Works standalone on a plane (`text("xy", "Hi")`), inside a
54
+ * `sketch()` (`text("Hi")`), or following a planar curve
55
+ * (`text("Hi", path)`).
56
+ */
57
+ export class Text extends ExtrudableGeometryBase {
58
+ text;
59
+ path;
60
+ _size = 10;
61
+ _font;
62
+ _weight = 400;
63
+ _italic = false;
64
+ _align = "left";
65
+ _lineSpacing = 1;
66
+ _letterSpacing = 0;
67
+ _pathOffset = 0;
68
+ _flip = false;
69
+ _startAt = 0;
70
+ _pathPlane = null;
71
+ constructor(text, targetPlane = null, path = null) {
72
+ super(targetPlane);
73
+ this.text = text;
74
+ this.path = path;
75
+ }
76
+ build() {
77
+ if (this.path) {
78
+ this.buildAlongPath();
79
+ return;
80
+ }
81
+ if (this._pathOffset !== 0 || this._flip || this._startAt !== 0) {
82
+ throw new BuildError("text: .offset(), .flip() and .startAt() only apply to text following a path.", "Use the text(string, path) form, or remove these modifiers.");
83
+ }
84
+ if (this._align === "space-between" || this._align === "space-around") {
85
+ throw new BuildError(`text: align('${this._align}') only applies to text following a path.`, "Use the text(string, path) form, or pick left/center/right.");
86
+ }
87
+ const plane = this.targetPlane
88
+ ? this.targetPlane.getPlane()
89
+ : this.getParent().getPlane();
90
+ const origin = this.targetPlane
91
+ ? plane.worldToLocal(this.targetPlane.getPlaneCenter())
92
+ : this.getCurrentPosition();
93
+ const font = FontRegistry.resolve({ font: this._font, weight: this._weight, italic: this._italic });
94
+ const edges = TextOutline.buildEdges(font, this.text, {
95
+ size: this._size,
96
+ align: this._align,
97
+ lineSpacing: this._lineSpacing,
98
+ letterSpacing: this._letterSpacing,
99
+ }, plane, origin);
100
+ this.addShapes(edges);
101
+ if (this.targetPlane) {
102
+ this.targetPlane.removeShapes(this);
103
+ }
104
+ }
105
+ buildAlongPath() {
106
+ // Guide curves are included: marking the path `.guide()` is the natural
107
+ // way to keep it out of the sketch profile while text follows it.
108
+ const shapes = this.path.getShapes({ excludeMeta: false, excludeGuide: false });
109
+ const pathEdges = shapes.flatMap(s => s.getSubShapes('edge'));
110
+ if (pathEdges.length === 0) {
111
+ throw new BuildError("text: path contains no edges.");
112
+ }
113
+ const wire = WireOps.makeWireFromEdges(pathEdges);
114
+ const sampler = new PathSampler(wire);
115
+ try {
116
+ const plane = this.resolvePathPlane(sampler);
117
+ this._pathPlane = plane;
118
+ // On a closed loop, normalize the (arbitrary) wire winding so text
119
+ // sits on the OUTSIDE by default; `.flip()` then moves it inside.
120
+ // A clockwise loop (w.r.t. the plane normal) already has its glyph
121
+ // "up" (normal × tangent) pointing outward.
122
+ let flip = this._flip;
123
+ if (sampler.closed && !WireOps.isCW(wire, plane.normal)) {
124
+ flip = !flip;
125
+ }
126
+ const font = FontRegistry.resolve({ font: this._font, weight: this._weight, italic: this._italic });
127
+ const edges = TextOutline.buildEdgesAlongPath(font, this.text, {
128
+ size: this._size,
129
+ align: this._align,
130
+ lineSpacing: this._lineSpacing,
131
+ letterSpacing: this._letterSpacing,
132
+ }, {
133
+ evalAt: (s) => sampler.evalAt(s),
134
+ length: sampler.length,
135
+ normal: plane.normal,
136
+ offset: this._pathOffset,
137
+ startAt: this._startAt,
138
+ flip,
139
+ closed: sampler.closed,
140
+ });
141
+ this.addShapes(edges);
142
+ }
143
+ finally {
144
+ sampler.dispose();
145
+ }
146
+ }
147
+ /**
148
+ * The plane the text lies in: the path object's own plane when it has one
149
+ * (sketch, planar primitive), otherwise a plane fitted through the path.
150
+ * Also verifies the path actually is planar.
151
+ */
152
+ resolvePathPlane(sampler) {
153
+ const samples = sampler.sample(64);
154
+ let plane = this.pathOwnPlane();
155
+ if (!plane) {
156
+ plane = fitPathPlane(samples, sampler.evalAt(0).tangent, sampler.length);
157
+ }
158
+ if (!plane) {
159
+ throw new BuildError("text: cannot derive the path's orientation — a straight-line path carries no plane of its own.", "Draw the path in a sketch (or use a planar primitive) so the text knows which way is up.");
160
+ }
161
+ const tol = Math.max(1e-5, sampler.length * 1e-6);
162
+ for (const p of samples) {
163
+ if (plane.distanceToPoint(p) > tol) {
164
+ throw new BuildError("text: path must be planar.", "Text can only follow a curve lying in a single plane (e.g. a sketch curve or a planar edge loop).");
165
+ }
166
+ }
167
+ return plane;
168
+ }
169
+ pathOwnPlane() {
170
+ if (this.path instanceof Sketch) {
171
+ return this.path.getPlane();
172
+ }
173
+ if (this.path instanceof ExtrudableGeometryBase) {
174
+ try {
175
+ return this.path.getPlane();
176
+ }
177
+ catch {
178
+ return null;
179
+ }
180
+ }
181
+ // Plain sketch geometry (arc, line, …) lies in its sketch's plane.
182
+ if (this.path instanceof GeometrySceneObject) {
183
+ const sketch = this.path.sketch;
184
+ return sketch ? sketch.getPlane() : null;
185
+ }
186
+ return null;
187
+ }
188
+ getPlane() {
189
+ if (this.path) {
190
+ if (!this._pathPlane) {
191
+ throw new Error("text: the path plane is resolved during build; render the scene first.");
192
+ }
193
+ return this._pathPlane;
194
+ }
195
+ return super.getPlane();
196
+ }
197
+ size(value) {
198
+ this._size = value;
199
+ return this;
200
+ }
201
+ font(name) {
202
+ this._font = name;
203
+ return this;
204
+ }
205
+ weight(value) {
206
+ this._weight = typeof value === "number" ? value : (WEIGHT_NAMES[value.toLowerCase()] ?? 400);
207
+ return this;
208
+ }
209
+ bold() {
210
+ this._weight = 700;
211
+ return this;
212
+ }
213
+ italic(value = true) {
214
+ this._italic = value;
215
+ return this;
216
+ }
217
+ align(value) {
218
+ this._align = value;
219
+ return this;
220
+ }
221
+ lineSpacing(value) {
222
+ this._lineSpacing = value;
223
+ return this;
224
+ }
225
+ letterSpacing(value) {
226
+ this._letterSpacing = value;
227
+ return this;
228
+ }
229
+ offset(value) {
230
+ this._pathOffset = value;
231
+ return this;
232
+ }
233
+ flip(value = true) {
234
+ this._flip = value;
235
+ return this;
236
+ }
237
+ startAt(distance) {
238
+ this._startAt = distance;
239
+ return this;
240
+ }
241
+ getType() {
242
+ return "text";
243
+ }
244
+ getDependencies() {
245
+ const deps = [];
246
+ if (this.targetPlane) {
247
+ deps.push(this.targetPlane);
248
+ }
249
+ if (this.path) {
250
+ deps.push(this.path);
251
+ }
252
+ return deps;
253
+ }
254
+ createCopy(remap) {
255
+ const targetPlane = this.targetPlane
256
+ ? (remap.get(this.targetPlane) || this.targetPlane)
257
+ : null;
258
+ const path = this.path
259
+ ? (remap.get(this.path) || this.path)
260
+ : null;
261
+ const copy = new Text(this.text, targetPlane, path);
262
+ copy._size = this._size;
263
+ copy._font = this._font;
264
+ copy._weight = this._weight;
265
+ copy._italic = this._italic;
266
+ copy._align = this._align;
267
+ copy._lineSpacing = this._lineSpacing;
268
+ copy._letterSpacing = this._letterSpacing;
269
+ copy._pathOffset = this._pathOffset;
270
+ copy._flip = this._flip;
271
+ copy._startAt = this._startAt;
272
+ return copy;
273
+ }
274
+ compareTo(other) {
275
+ if (!(other instanceof Text)) {
276
+ return false;
277
+ }
278
+ if (!super.compareTo(other)) {
279
+ return false;
280
+ }
281
+ if (this.targetPlane?.constructor !== other.targetPlane?.constructor) {
282
+ return false;
283
+ }
284
+ if (this.targetPlane && other.targetPlane && !this.targetPlane.compareTo(other.targetPlane)) {
285
+ return false;
286
+ }
287
+ if (this.path?.constructor !== other.path?.constructor) {
288
+ return false;
289
+ }
290
+ if (this.path && other.path && !this.path.compareTo(other.path)) {
291
+ return false;
292
+ }
293
+ return this.text === other.text
294
+ && this._size === other._size
295
+ && this._font === other._font
296
+ && this._weight === other._weight
297
+ && this._italic === other._italic
298
+ && this._align === other._align
299
+ && this._lineSpacing === other._lineSpacing
300
+ && this._letterSpacing === other._letterSpacing
301
+ && this._pathOffset === other._pathOffset
302
+ && this._flip === other._flip
303
+ && this._startAt === other._startAt;
304
+ }
305
+ serialize() {
306
+ return {
307
+ text: this.text,
308
+ size: this._size,
309
+ font: this._font,
310
+ weight: this._weight,
311
+ italic: this._italic,
312
+ align: this._align,
313
+ lineSpacing: this._lineSpacing,
314
+ letterSpacing: this._letterSpacing,
315
+ offset: this._pathOffset,
316
+ flip: this._flip,
317
+ startAt: this._startAt,
318
+ };
319
+ }
320
+ }
@@ -1,9 +1,11 @@
1
1
  import { TransformablePrimitive } from "../common/transformable-primitive.js";
2
+ import { BuildSceneObjectContext, SceneObject } from "../common/scene-object.js";
2
3
  export declare class Cylinder extends TransformablePrimitive {
3
4
  radius: number;
4
5
  height: number;
5
6
  constructor(radius: number, height: number);
6
- build(): void;
7
+ build(context?: BuildSceneObjectContext): void;
8
+ createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
7
9
  compareTo(other: Cylinder): boolean;
8
10
  getType(): string;
9
11
  serialize(): {
@@ -8,9 +8,12 @@ export class Cylinder extends TransformablePrimitive {
8
8
  this.radius = radius;
9
9
  this.height = height;
10
10
  }
11
- build() {
11
+ build(context) {
12
12
  const cyl = Primitives.makeCylinder(this.radius, this.height);
13
- this.addShapes([cyl]);
13
+ this.addPrimitiveShape(cyl, context);
14
+ }
15
+ createCopy(remap) {
16
+ return new Cylinder(this.radius, this.height).syncPrimitiveWith(this);
14
17
  }
15
18
  compareTo(other) {
16
19
  if (!(other instanceof Cylinder)) {
@@ -87,6 +87,7 @@ export declare abstract class ExtrudeBase extends SceneObject implements IExtrud
87
87
  */
88
88
  protected finalizeAndFuse(shapes: Shape[], classified: ClassifiedFaces, context: BuildSceneObjectContext, fuseOpts?: {
89
89
  glue?: 'full' | 'shift';
90
+ skipSimplify?: boolean;
90
91
  }): void;
91
92
  /**
92
93
  * One-shot edge classification: derive start/end/side/internal/cap edges
@@ -11,6 +11,7 @@ export declare class ExtrudeToFace extends ExtrudeBase {
11
11
  private createAdvancedExtrude;
12
12
  private resizePlanarFace;
13
13
  private resizeCylindricalFace;
14
+ private resizeConicalFace;
14
15
  /**
15
16
  * Computes the signed distance from the sketch plane to the farthest
16
17
  * bounding-box corner of the target face, measured along the sketch
@@ -139,6 +139,9 @@ export class ExtrudeToFace extends ExtrudeBase {
139
139
  if (surfaceType === 'cylinder') {
140
140
  splitTargetFace = this.resizeCylindricalFace(targetFace);
141
141
  }
142
+ else if (surfaceType === 'cone') {
143
+ splitTargetFace = this.resizeConicalFace(targetFace);
144
+ }
142
145
  else {
143
146
  splitTargetFace = targetFace;
144
147
  }
@@ -157,6 +160,9 @@ export class ExtrudeToFace extends ExtrudeBase {
157
160
  resizeCylindricalFace(targetFace) {
158
161
  return FaceQuery.makeInfiniteCylindricalFace(targetFace, this.getEndOffset());
159
162
  }
163
+ resizeConicalFace(targetFace) {
164
+ return FaceQuery.makeInfiniteConicalFace(targetFace, this.getEndOffset());
165
+ }
160
166
  /**
161
167
  * Computes the signed distance from the sketch plane to the farthest
162
168
  * bounding-box corner of the target face, measured along the sketch
@@ -8,7 +8,7 @@ export declare class Fillet extends SceneObject {
8
8
  validate(): void;
9
9
  build(context: BuildSceneObjectContext): void;
10
10
  doBuild(sceneObjectsMap: Map<SceneObject, Shape[]>, selections: SceneObject[]): {
11
- addedShapes: Shape<import("occjs-wrapper").TopoDS_Shape>[];
11
+ addedShapes: Shape<import("ocjs-fluidcad").TopoDS_Shape>[];
12
12
  removedShapes: {
13
13
  shape: Shape;
14
14
  owner: SceneObject;
@@ -0,0 +1,41 @@
1
+ import { BuildSceneObjectContext, SceneObject } from "../common/scene-object.js";
2
+ import { AxisObjectBase } from "./axis-renderable-base.js";
3
+ import { IHelix } from "../core/interfaces.js";
4
+ export declare class Helix extends SceneObject implements IHelix {
5
+ source: AxisObjectBase | SceneObject;
6
+ private _pitch?;
7
+ private _turns?;
8
+ private _startOffset;
9
+ private _endOffset;
10
+ private _height?;
11
+ private _radius?;
12
+ private _endRadius?;
13
+ constructor(source: AxisObjectBase | SceneObject);
14
+ pitch(value: number): this;
15
+ turns(value: number): this;
16
+ startOffset(value: number): this;
17
+ endOffset(value: number): this;
18
+ height(value: number): this;
19
+ radius(value: number): this;
20
+ endRadius(value: number): this;
21
+ validate(): void;
22
+ build(_context?: BuildSceneObjectContext): void;
23
+ private deriveTurnsFromHeight;
24
+ private resolveSource;
25
+ private resolveFace;
26
+ private resolveEdge;
27
+ getType(): string;
28
+ getDependencies(): SceneObject[];
29
+ createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
30
+ compareTo(other: SceneObject): boolean;
31
+ serialize(): {
32
+ source: any;
33
+ pitch: number;
34
+ turns: number;
35
+ startOffset: number;
36
+ endOffset: number;
37
+ height: number;
38
+ radius: number;
39
+ endRadius: number;
40
+ };
41
+ }