fluidcad 0.0.34 → 0.0.35
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.
- package/README.md +69 -0
- package/bin/commands/login.js +120 -0
- package/bin/commands/pack.js +49 -0
- package/bin/commands/publish.js +136 -0
- package/bin/fluidcad.js +6 -0
- package/bin/lib/api-client.js +40 -0
- package/bin/lib/browser.js +16 -0
- package/bin/lib/config.js +39 -0
- package/bin/lib/model-config.js +38 -0
- package/bin/lib/workspace.js +57 -0
- package/lib/dist/common/shape-factory.d.ts +2 -1
- package/lib/dist/common/shape-factory.js +4 -0
- package/lib/dist/common/transformable-primitive.d.ts +6 -5
- package/lib/dist/common/transformable-primitive.js +8 -7
- package/lib/dist/common/vertex.js +0 -1
- package/lib/dist/core/2d/aline.d.ts +4 -3
- package/lib/dist/core/2d/aline.js +3 -2
- package/lib/dist/core/2d/arc.d.ts +3 -2
- package/lib/dist/core/2d/arc.js +4 -3
- package/lib/dist/core/2d/bezier.d.ts +8 -6
- package/lib/dist/core/2d/circle.d.ts +4 -3
- package/lib/dist/core/2d/circle.js +3 -2
- package/lib/dist/core/2d/ellipse.d.ts +5 -4
- package/lib/dist/core/2d/ellipse.js +5 -4
- package/lib/dist/core/2d/hline.d.ts +4 -3
- package/lib/dist/core/2d/hline.js +5 -3
- package/lib/dist/core/2d/line.js +1 -0
- package/lib/dist/core/2d/offset.d.ts +3 -2
- package/lib/dist/core/2d/offset.js +6 -5
- package/lib/dist/core/2d/polygon.d.ts +5 -4
- package/lib/dist/core/2d/polygon.js +10 -9
- package/lib/dist/core/2d/rect.d.ts +4 -3
- package/lib/dist/core/2d/rect.js +10 -9
- package/lib/dist/core/2d/slot.d.ts +14 -6
- package/lib/dist/core/2d/slot.js +19 -8
- package/lib/dist/core/2d/vline.d.ts +4 -3
- package/lib/dist/core/2d/vline.js +5 -3
- package/lib/dist/core/chamfer.d.ts +5 -4
- package/lib/dist/core/chamfer.js +7 -6
- package/lib/dist/core/color.d.ts +3 -2
- package/lib/dist/core/color.js +2 -1
- package/lib/dist/core/cut.d.ts +4 -3
- package/lib/dist/core/cut.js +5 -4
- package/lib/dist/core/cylinder.d.ts +2 -1
- package/lib/dist/core/cylinder.js +2 -1
- package/lib/dist/core/draft.d.ts +3 -2
- package/lib/dist/core/draft.js +3 -2
- package/lib/dist/core/extrude.d.ts +4 -3
- package/lib/dist/core/extrude.js +5 -4
- package/lib/dist/core/fillet.d.ts +5 -4
- package/lib/dist/core/fillet.js +6 -5
- package/lib/dist/core/index.d.ts +1 -0
- package/lib/dist/core/index.js +1 -0
- package/lib/dist/core/interfaces.d.ts +25 -24
- package/lib/dist/core/param.d.ts +74 -0
- package/lib/dist/core/param.js +147 -0
- package/lib/dist/core/repeat.d.ts +2 -1
- package/lib/dist/core/repeat.js +10 -8
- package/lib/dist/core/revolve.d.ts +2 -1
- package/lib/dist/core/revolve.js +3 -2
- package/lib/dist/core/rib.d.ts +3 -2
- package/lib/dist/core/rib.js +6 -2
- package/lib/dist/core/rotate.d.ts +5 -4
- package/lib/dist/core/rotate.js +4 -3
- package/lib/dist/core/shell.d.ts +3 -2
- package/lib/dist/core/shell.js +3 -2
- package/lib/dist/core/sphere.d.ts +3 -2
- package/lib/dist/core/sphere.js +2 -1
- package/lib/dist/core/translate.d.ts +7 -6
- package/lib/dist/core/translate.js +6 -5
- package/lib/dist/features/2d/arc.js +5 -5
- package/lib/dist/features/2d/bezier.js +16 -16
- package/lib/dist/features/2d/circle.js +4 -0
- package/lib/dist/features/2d/ellipse.js +4 -0
- package/lib/dist/features/2d/hline.d.ts +3 -0
- package/lib/dist/features/2d/hline.js +9 -2
- package/lib/dist/features/2d/line.d.ts +3 -0
- package/lib/dist/features/2d/line.js +11 -3
- package/lib/dist/features/2d/sketch.js +5 -1
- package/lib/dist/features/2d/slot.d.ts +5 -0
- package/lib/dist/features/2d/slot.js +52 -7
- package/lib/dist/features/2d/tarc-to-point-tangent.js +3 -0
- package/lib/dist/features/2d/tarc-to-point.js +3 -0
- package/lib/dist/features/2d/tarc-with-tangent.js +3 -0
- package/lib/dist/features/2d/tarc.js +3 -0
- package/lib/dist/features/2d/vline.d.ts +3 -0
- package/lib/dist/features/2d/vline.js +9 -2
- package/lib/dist/features/copy-circular.d.ts +4 -3
- package/lib/dist/features/copy-circular.js +16 -9
- package/lib/dist/features/copy-circular2d.js +16 -9
- package/lib/dist/features/copy-linear.d.ts +4 -3
- package/lib/dist/features/copy-linear.js +18 -12
- package/lib/dist/features/copy-linear2d.js +18 -12
- package/lib/dist/features/extrude-base.d.ts +4 -3
- package/lib/dist/features/extrude-base.js +10 -3
- package/lib/dist/features/mirror-shape2d.js +2 -2
- package/lib/dist/features/repeat-base.d.ts +13 -0
- package/lib/dist/features/repeat-base.js +21 -0
- package/lib/dist/features/repeat-circular.d.ts +6 -5
- package/lib/dist/features/repeat-circular.js +3 -6
- package/lib/dist/features/repeat-linear.d.ts +7 -7
- package/lib/dist/features/repeat-linear.js +3 -6
- package/lib/dist/index.d.ts +5 -0
- package/lib/dist/index.js +8 -1
- package/lib/dist/io/file-import.d.ts +7 -0
- package/lib/dist/io/file-import.js +30 -10
- package/lib/dist/math/lazy-matrix.d.ts +5 -0
- package/lib/dist/math/lazy-matrix.js +78 -10
- package/lib/dist/oc/boolean-ops.d.ts +2 -2
- package/lib/dist/param-registry.d.ts +34 -0
- package/lib/dist/param-registry.js +60 -0
- package/lib/dist/rendering/mesh-builder.js +2 -1
- package/lib/dist/tests/features/copy-circular.test.js +1 -1
- package/lib/dist/tests/features/copy-linear.test.js +10 -10
- package/lib/dist/tests/features/repeat-user-repro-cache.test.d.ts +1 -0
- package/lib/dist/tests/features/repeat-user-repro-cache.test.js +97 -0
- package/lib/dist/tsconfig.tsbuildinfo +1 -1
- package/llm-docs/api/bezier.md +10 -11
- package/llm-docs/api/index.json +1 -1
- package/llm-docs/api/types/arc-points.md +2 -2
- package/llm-docs/api/types/cut.md +10 -10
- package/llm-docs/api/types/extrude.md +10 -10
- package/llm-docs/api/types/loft.md +6 -6
- package/llm-docs/api/types/revolve.md +6 -6
- package/llm-docs/api/types/rib.md +2 -2
- package/llm-docs/api/types/slot.md +2 -2
- package/llm-docs/api/types/sweep.md +10 -10
- package/llm-docs/api/types/transformable.md +14 -14
- package/llm-docs/index.json +12 -12
- package/mcp/dist/client.d.ts +1 -0
- package/mcp/dist/client.js +8 -1
- package/mcp/dist/server.js +14 -1
- package/mcp/dist/tools/engine.d.ts +16 -0
- package/mcp/dist/tools/engine.js +45 -0
- package/package.json +9 -3
- package/server/dist/api.d.ts +37 -0
- package/server/dist/api.js +44 -0
- package/server/dist/code-editor.d.ts +64 -0
- package/server/dist/code-editor.js +520 -2
- package/server/dist/fluidcad-server.d.ts +68 -1
- package/server/dist/fluidcad-server.js +224 -88
- package/server/dist/host/blocked-imports.d.ts +8 -0
- package/server/dist/host/blocked-imports.js +30 -0
- package/server/dist/{vite-manager.d.ts → host/local-scene-host.d.ts} +3 -1
- package/server/dist/{vite-manager.js → host/local-scene-host.js} +6 -26
- package/server/dist/host/scene-host.d.ts +19 -0
- package/server/dist/host/scene-host.js +1 -0
- package/server/dist/index.js +24 -117
- package/server/dist/model-package/capture-params.d.ts +19 -0
- package/server/dist/model-package/capture-params.js +42 -0
- package/server/dist/model-package/pack.d.ts +23 -0
- package/server/dist/model-package/pack.js +229 -0
- package/server/dist/model-package/types.d.ts +78 -0
- package/server/dist/model-package/types.js +17 -0
- package/server/dist/routes/hit-test.d.ts +3 -0
- package/server/dist/routes/hit-test.js +17 -0
- package/server/dist/routes/pack.d.ts +10 -0
- package/server/dist/routes/pack.js +47 -0
- package/server/dist/routes/params.d.ts +3 -0
- package/server/dist/routes/params.js +75 -0
- package/server/dist/routes/sketch-edits.d.ts +3 -0
- package/server/dist/routes/sketch-edits.js +542 -0
- package/server/dist/routes/timeline.d.ts +3 -0
- package/server/dist/routes/timeline.js +49 -0
- package/server/dist/server-core.d.ts +53 -0
- package/server/dist/server-core.js +147 -0
- package/server/dist/ws-protocol.d.ts +101 -2
- package/ui/dist/assets/index-CDJmUpFI.css +2 -0
- package/ui/dist/assets/index-MRqwG9Vh.js +5417 -0
- package/ui/dist/index.html +2 -2
- package/server/dist/routes/actions.d.ts +0 -3
- package/server/dist/routes/actions.js +0 -309
- package/ui/dist/assets/index-BdqrMDRu.js +0 -4946
- package/ui/dist/assets/index-DR7c2Qk9.css +0 -2
package/lib/dist/core/shell.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Shell } from "../features/shell.js";
|
|
2
2
|
import { SceneObject } from "../common/scene-object.js";
|
|
3
3
|
import { registerBuilder } from "../index.js";
|
|
4
|
+
import { isNumberParam, resolveParam } from "./param.js";
|
|
4
5
|
function build(context) {
|
|
5
6
|
return function shell() {
|
|
6
7
|
const args = Array.from(arguments);
|
|
@@ -14,8 +15,8 @@ function build(context) {
|
|
|
14
15
|
selections.push(implicit);
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
|
-
const thickness = (args.length >= 1 &&
|
|
18
|
-
? args[0]
|
|
18
|
+
const thickness = (args.length >= 1 && isNumberParam(args[0]))
|
|
19
|
+
? resolveParam(args[0])
|
|
19
20
|
: 2.5;
|
|
20
21
|
for (const sel of selections) {
|
|
21
22
|
context.addSceneObject(sel);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { ITransformable } from "./interfaces.js";
|
|
2
|
+
import { type NumberParam } from "./param.js";
|
|
2
3
|
interface SphereFunction {
|
|
3
4
|
/**
|
|
4
5
|
* Creates a full sphere with the given radius.
|
|
5
6
|
* @param radius - The sphere radius
|
|
6
7
|
*/
|
|
7
|
-
(radius:
|
|
8
|
+
(radius: NumberParam): ITransformable;
|
|
8
9
|
/**
|
|
9
10
|
* Creates a partial sphere with the given radius and sweep angle.
|
|
10
11
|
* @param radius - The sphere radius
|
|
11
12
|
* @param angle - The sweep angle in degrees
|
|
12
13
|
*/
|
|
13
|
-
(radius:
|
|
14
|
+
(radius: NumberParam, angle: NumberParam): ITransformable;
|
|
14
15
|
}
|
|
15
16
|
declare const _default: SphereFunction;
|
|
16
17
|
export default _default;
|
package/lib/dist/core/sphere.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Sphere } from "../features/sphere.js";
|
|
2
2
|
import { rad } from "../helpers/math-helpers.js";
|
|
3
3
|
import { registerBuilder } from "../index.js";
|
|
4
|
+
import { resolveParam } from "./param.js";
|
|
4
5
|
function build(context) {
|
|
5
6
|
return function sphere(radius, angle = 360) {
|
|
6
|
-
const sphere = new Sphere(radius, rad(angle));
|
|
7
|
+
const sphere = new Sphere(resolveParam(radius), rad(resolveParam(angle)));
|
|
7
8
|
context.addSceneObject(sphere);
|
|
8
9
|
return sphere;
|
|
9
10
|
};
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import { PointLike } from "../math/point.js";
|
|
2
2
|
import { ISceneObject, ITranslate } from "./interfaces.js";
|
|
3
|
+
import { type NumberParam, type BooleanParam } from "./param.js";
|
|
3
4
|
interface TranslateFunction {
|
|
4
5
|
/**
|
|
5
6
|
* Translates objects along the X axis.
|
|
6
7
|
* @param x - The X distance
|
|
7
8
|
* @param targets - The objects to translate (defaults to last object)
|
|
8
9
|
*/
|
|
9
|
-
(x:
|
|
10
|
+
(x: NumberParam, ...targets: ISceneObject[]): ITranslate;
|
|
10
11
|
/**
|
|
11
12
|
* Translates objects along the X axis, optionally making a copy.
|
|
12
13
|
* @param x - The X distance
|
|
13
14
|
* @param copy - Whether to copy instead of move
|
|
14
15
|
* @param targets - The objects to translate (defaults to last object)
|
|
15
16
|
*/
|
|
16
|
-
(x:
|
|
17
|
+
(x: NumberParam, copy: BooleanParam, ...targets: ISceneObject[]): ITranslate;
|
|
17
18
|
/**
|
|
18
19
|
* Translates objects along the X and Y axes.
|
|
19
20
|
* @param x - The X distance
|
|
20
21
|
* @param y - The Y distance
|
|
21
22
|
* @param targets - The objects to translate (defaults to last object)
|
|
22
23
|
*/
|
|
23
|
-
(x:
|
|
24
|
+
(x: NumberParam, y: NumberParam, ...targets: ISceneObject[]): ITranslate;
|
|
24
25
|
/**
|
|
25
26
|
* Translates objects along the X and Y axes, optionally making a copy.
|
|
26
27
|
* @param x - The X distance
|
|
@@ -28,7 +29,7 @@ interface TranslateFunction {
|
|
|
28
29
|
* @param copy - Whether to copy instead of move
|
|
29
30
|
* @param targets - The objects to translate (defaults to last object)
|
|
30
31
|
*/
|
|
31
|
-
(x:
|
|
32
|
+
(x: NumberParam, y: NumberParam, copy: BooleanParam, ...targets: ISceneObject[]): ITranslate;
|
|
32
33
|
/**
|
|
33
34
|
* Translates objects along all three axes.
|
|
34
35
|
* @param x - The X distance
|
|
@@ -36,7 +37,7 @@ interface TranslateFunction {
|
|
|
36
37
|
* @param z - The Z distance
|
|
37
38
|
* @param targets - The objects to translate (defaults to last object)
|
|
38
39
|
*/
|
|
39
|
-
(x:
|
|
40
|
+
(x: NumberParam, y: NumberParam, z: NumberParam, ...targets: ISceneObject[]): ITranslate;
|
|
40
41
|
/**
|
|
41
42
|
* Translates objects along all three axes, optionally making a copy.
|
|
42
43
|
* @param x - The X distance
|
|
@@ -45,7 +46,7 @@ interface TranslateFunction {
|
|
|
45
46
|
* @param copy - Whether to copy instead of move
|
|
46
47
|
* @param targets - The objects to translate (defaults to last object)
|
|
47
48
|
*/
|
|
48
|
-
(x:
|
|
49
|
+
(x: NumberParam, y: NumberParam, z: NumberParam, copy: BooleanParam, ...targets: ISceneObject[]): ITranslate;
|
|
49
50
|
/**
|
|
50
51
|
* Translates objects by a point-like offset.
|
|
51
52
|
* @param distance - The offset as a point
|
|
@@ -5,6 +5,7 @@ import { Point } from "../math/point.js";
|
|
|
5
5
|
import { SceneObject } from "../common/scene-object.js";
|
|
6
6
|
import { Vertex } from "../common/vertex.js";
|
|
7
7
|
import { LazyVertex } from "../features/lazy-vertex.js";
|
|
8
|
+
import { isNumberParam, isBooleanParam, resolveParam } from "./param.js";
|
|
8
9
|
function build(context) {
|
|
9
10
|
return function translate() {
|
|
10
11
|
const args = Array.from(arguments);
|
|
@@ -14,12 +15,12 @@ function build(context) {
|
|
|
14
15
|
targets.unshift(args.pop());
|
|
15
16
|
}
|
|
16
17
|
// Extract copy flag from the end (if boolean)
|
|
17
|
-
const copy =
|
|
18
|
+
const copy = isBooleanParam(args[args.length - 1]) ? resolveParam(args.pop()) : false;
|
|
18
19
|
// translate(x, y?, z?)
|
|
19
|
-
if (
|
|
20
|
-
const x = args[0];
|
|
21
|
-
const y = args[1]
|
|
22
|
-
const z = args[2]
|
|
20
|
+
if (isNumberParam(args[0])) {
|
|
21
|
+
const x = resolveParam(args[0]);
|
|
22
|
+
const y = isNumberParam(args[1]) ? resolveParam(args[1]) : 0;
|
|
23
|
+
const z = isNumberParam(args[2]) ? resolveParam(args[2]) : 0;
|
|
23
24
|
const vertex = Vertex.fromPoint(new Point(x, y, z));
|
|
24
25
|
const lazyVertex = LazyVertex.fromVertex(vertex);
|
|
25
26
|
const translate = new Translate(lazyVertex, copy, ...targets);
|
|
@@ -115,7 +115,7 @@ export class Arc extends GeometrySceneObject {
|
|
|
115
115
|
this.setTangent(new Point2D(tx, ty));
|
|
116
116
|
this.setState('start', Vertex.fromPoint2D(startPt));
|
|
117
117
|
this.setState('end', Vertex.fromPoint2D(endPt));
|
|
118
|
-
const centerVertex = Vertex.
|
|
118
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
119
119
|
centerVertex.markAsMetaShape();
|
|
120
120
|
this.addShape(centerVertex);
|
|
121
121
|
this.addShape(edge);
|
|
@@ -161,7 +161,7 @@ export class Arc extends GeometrySceneObject {
|
|
|
161
161
|
this.setTangent(new Point2D(endTx, endTy));
|
|
162
162
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
163
163
|
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
164
|
-
const centerVertex = Vertex.
|
|
164
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
165
165
|
centerVertex.markAsMetaShape();
|
|
166
166
|
this.addShape(centerVertex);
|
|
167
167
|
this.addShape(edge);
|
|
@@ -209,7 +209,7 @@ export class Arc extends GeometrySceneObject {
|
|
|
209
209
|
this.setTangent(new Point2D(endTx, endTy));
|
|
210
210
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
211
211
|
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
212
|
-
const centerVertex = Vertex.
|
|
212
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
213
213
|
centerVertex.markAsMetaShape();
|
|
214
214
|
this.addShape(centerVertex);
|
|
215
215
|
this.addShape(edge);
|
|
@@ -269,7 +269,7 @@ export class Arc extends GeometrySceneObject {
|
|
|
269
269
|
this.setTangent(new Point2D(tx, ty));
|
|
270
270
|
this.setState('start', Vertex.fromPoint2D(startPt));
|
|
271
271
|
this.setState('end', Vertex.fromPoint2D(endPt));
|
|
272
|
-
const centerVertex = Vertex.
|
|
272
|
+
const centerVertex = Vertex.fromPoint(plane.localToWorld(actualCenter));
|
|
273
273
|
centerVertex.markAsMetaShape();
|
|
274
274
|
this.addShape(centerVertex);
|
|
275
275
|
this.addShape(edge);
|
|
@@ -317,7 +317,7 @@ export class Arc extends GeometrySceneObject {
|
|
|
317
317
|
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
318
318
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
319
319
|
this.setState('end', Vertex.fromPoint2D(endPoint));
|
|
320
|
-
const centerVertex = Vertex.
|
|
320
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
321
321
|
centerVertex.markAsMetaShape();
|
|
322
322
|
this.addShape(centerVertex);
|
|
323
323
|
const sign = cw ? -1 : 1;
|
|
@@ -11,16 +11,20 @@ export class BezierCurve extends GeometrySceneObject {
|
|
|
11
11
|
this.controlPoints = controlPoints;
|
|
12
12
|
}
|
|
13
13
|
build() {
|
|
14
|
-
|
|
14
|
+
const points = this.controlPoints.map(cp => cp.asPoint2D());
|
|
15
|
+
if (points.length < 2) {
|
|
16
|
+
// 0 args: interactive placeholder. 1 arg: start placed, no curve yet.
|
|
17
|
+
if (points.length === 1) {
|
|
18
|
+
this.setState('start', Vertex.fromPoint2D(points[0]));
|
|
19
|
+
this.setCurrentPosition(points[0]);
|
|
20
|
+
}
|
|
15
21
|
return;
|
|
16
22
|
}
|
|
17
23
|
const plane = this.sketch.getPlane();
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
// Poles:
|
|
21
|
-
|
|
22
|
-
const poles2D = [currentPos, ...points];
|
|
23
|
-
const polesWorld = poles2D.map(p => plane.localToWorld(p));
|
|
24
|
+
const startPoint = points[0];
|
|
25
|
+
const endPoint = points[points.length - 1];
|
|
26
|
+
// Poles: all args in order — first is start, last is endpoint, middle are controls.
|
|
27
|
+
const polesWorld = points.map(p => plane.localToWorld(p));
|
|
24
28
|
const bezierCurve = Geometry.makeBezierCurve(polesWorld);
|
|
25
29
|
// Compute tangent at endpoint before creating the edge
|
|
26
30
|
const oc = getOC();
|
|
@@ -29,11 +33,9 @@ export class BezierCurve extends GeometrySceneObject {
|
|
|
29
33
|
bezierCurve.D1(bezierCurve.LastParameter(), gpP, gpV);
|
|
30
34
|
const tangentWorld = Convert.toVector3d(gpV, true);
|
|
31
35
|
gpP.delete();
|
|
32
|
-
// Project tangent to 2D sketch coordinates
|
|
33
36
|
const tangent2D = new Point2D(tangentWorld.dot(plane.xDirection), tangentWorld.dot(plane.yDirection)).normalize();
|
|
34
37
|
const edge = Geometry.makeEdgeFromBezier(bezierCurve);
|
|
35
|
-
|
|
36
|
-
this.setState('start', Vertex.fromPoint2D(currentPos));
|
|
38
|
+
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
37
39
|
this.setState('end', Vertex.fromPoint2D(endPoint));
|
|
38
40
|
this.addShape(edge);
|
|
39
41
|
this.setTangent(tangent2D);
|
|
@@ -63,14 +65,12 @@ export class BezierCurve extends GeometrySceneObject {
|
|
|
63
65
|
return `bezier-${this.controlPoints.length}`;
|
|
64
66
|
}
|
|
65
67
|
serialize() {
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
return [p.x, p.y];
|
|
70
|
-
});
|
|
68
|
+
const points = this.controlPoints.map(cp => cp.asPoint2D());
|
|
69
|
+
const start = points[0];
|
|
70
|
+
const resolved = points.slice(1).map(p => [p.x, p.y]);
|
|
71
71
|
return {
|
|
72
72
|
controlPoints: this.controlPoints,
|
|
73
|
-
startPoint: [
|
|
73
|
+
startPoint: start ? [start.x, start.y] : null,
|
|
74
74
|
resolvedPoints: resolved,
|
|
75
75
|
};
|
|
76
76
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Geometry } from "../../oc/geometry.js";
|
|
2
|
+
import { Vertex } from "../../common/vertex.js";
|
|
2
3
|
import { ExtrudableGeometryBase } from "./extrudable-base.js";
|
|
3
4
|
export class Circle extends ExtrudableGeometryBase {
|
|
4
5
|
diameter;
|
|
@@ -21,6 +22,9 @@ export class Circle extends ExtrudableGeometryBase {
|
|
|
21
22
|
const circle = Geometry.makeCircle(plane.localToWorld(center), radius, plane.normal);
|
|
22
23
|
let edge = Geometry.makeEdgeFromCircle(circle);
|
|
23
24
|
this.addShape(edge);
|
|
25
|
+
const centerVertex = Vertex.fromPoint2D(center);
|
|
26
|
+
centerVertex.markAsMetaShape();
|
|
27
|
+
this.addShape(centerVertex);
|
|
24
28
|
if (this.sketch) {
|
|
25
29
|
this.setCurrentPosition(center);
|
|
26
30
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Geometry } from "../../oc/geometry.js";
|
|
2
|
+
import { Vertex } from "../../common/vertex.js";
|
|
2
3
|
import { ExtrudableGeometryBase } from "./extrudable-base.js";
|
|
3
4
|
export class Ellipse extends ExtrudableGeometryBase {
|
|
4
5
|
rx;
|
|
@@ -29,6 +30,9 @@ export class Ellipse extends ExtrudableGeometryBase {
|
|
|
29
30
|
const majorAxisDir = rxIsMajor ? plane.xDirection : plane.yDirection;
|
|
30
31
|
const edge = Geometry.makeEllipseEdge(plane.localToWorld(center), major, minor, plane.normal, majorAxisDir);
|
|
31
32
|
this.addShape(edge);
|
|
33
|
+
const centerVertex = Vertex.fromPoint2D(center);
|
|
34
|
+
centerVertex.markAsMetaShape();
|
|
35
|
+
this.addShape(centerVertex);
|
|
32
36
|
if (this.sketch) {
|
|
33
37
|
this.setCurrentPosition(center);
|
|
34
38
|
}
|
|
@@ -6,8 +6,10 @@ export declare class HorizontalLine extends GeometrySceneObject implements IHLin
|
|
|
6
6
|
distanceOrTarget: number | SceneObject;
|
|
7
7
|
private targetPlane;
|
|
8
8
|
private _centered;
|
|
9
|
+
private _hasExplicitStart;
|
|
9
10
|
constructor(distanceOrTarget: number | SceneObject, targetPlane?: PlaneObjectBase);
|
|
10
11
|
centered(value?: boolean): this;
|
|
12
|
+
setHasExplicitStart(value?: boolean): this;
|
|
11
13
|
build(): void;
|
|
12
14
|
getDependencies(): SceneObject[];
|
|
13
15
|
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
@@ -17,5 +19,6 @@ export declare class HorizontalLine extends GeometrySceneObject implements IHLin
|
|
|
17
19
|
serialize(): {
|
|
18
20
|
distance: number;
|
|
19
21
|
centered: boolean;
|
|
22
|
+
hasExplicitStart: boolean;
|
|
20
23
|
};
|
|
21
24
|
}
|
|
@@ -8,6 +8,7 @@ export class HorizontalLine extends GeometrySceneObject {
|
|
|
8
8
|
distanceOrTarget;
|
|
9
9
|
targetPlane;
|
|
10
10
|
_centered = false;
|
|
11
|
+
_hasExplicitStart = false;
|
|
11
12
|
constructor(distanceOrTarget, targetPlane = null) {
|
|
12
13
|
super();
|
|
13
14
|
this.distanceOrTarget = distanceOrTarget;
|
|
@@ -17,6 +18,10 @@ export class HorizontalLine extends GeometrySceneObject {
|
|
|
17
18
|
this._centered = value;
|
|
18
19
|
return this;
|
|
19
20
|
}
|
|
21
|
+
setHasExplicitStart(value = true) {
|
|
22
|
+
this._hasExplicitStart = value;
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
20
25
|
build() {
|
|
21
26
|
const plane = this.targetPlane?.getPlane() || this.sketch.getPlane();
|
|
22
27
|
const currentPos = this.targetPlane
|
|
@@ -78,6 +83,7 @@ export class HorizontalLine extends GeometrySceneObject {
|
|
|
78
83
|
: this.distanceOrTarget;
|
|
79
84
|
const copy = new HorizontalLine(distanceOrTarget, targetPlane);
|
|
80
85
|
copy.centered(this._centered);
|
|
86
|
+
copy._hasExplicitStart = this._hasExplicitStart;
|
|
81
87
|
return copy;
|
|
82
88
|
}
|
|
83
89
|
compareTo(other) {
|
|
@@ -104,7 +110,7 @@ export class HorizontalLine extends GeometrySceneObject {
|
|
|
104
110
|
else if (this.distanceOrTarget !== other.distanceOrTarget) {
|
|
105
111
|
return false;
|
|
106
112
|
}
|
|
107
|
-
return this._centered === other._centered;
|
|
113
|
+
return this._centered === other._centered && this._hasExplicitStart === other._hasExplicitStart;
|
|
108
114
|
}
|
|
109
115
|
getType() {
|
|
110
116
|
return 'line';
|
|
@@ -115,7 +121,8 @@ export class HorizontalLine extends GeometrySceneObject {
|
|
|
115
121
|
serialize() {
|
|
116
122
|
return {
|
|
117
123
|
distance: typeof this.distanceOrTarget === 'number' ? this.distanceOrTarget : null,
|
|
118
|
-
centered: this._centered
|
|
124
|
+
centered: this._centered,
|
|
125
|
+
hasExplicitStart: this._hasExplicitStart,
|
|
119
126
|
};
|
|
120
127
|
}
|
|
121
128
|
}
|
|
@@ -5,7 +5,9 @@ import { GeometrySceneObject } from "./geometry.js";
|
|
|
5
5
|
export declare class LineTo extends GeometrySceneObject {
|
|
6
6
|
endPoint: LazyVertex;
|
|
7
7
|
private targetPlane;
|
|
8
|
+
private _hasExplicitStart;
|
|
8
9
|
constructor(endPoint: LazyVertex, targetPlane?: PlaneObjectBase);
|
|
10
|
+
setHasExplicitStart(value?: boolean): this;
|
|
9
11
|
build(): void;
|
|
10
12
|
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
11
13
|
compareTo(other: LineTo): boolean;
|
|
@@ -13,5 +15,6 @@ export declare class LineTo extends GeometrySceneObject {
|
|
|
13
15
|
getUniqueType(): string;
|
|
14
16
|
serialize(): {
|
|
15
17
|
end: LazyVertex;
|
|
18
|
+
hasExplicitStart: boolean;
|
|
16
19
|
};
|
|
17
20
|
}
|
|
@@ -4,11 +4,16 @@ import { GeometrySceneObject } from "./geometry.js";
|
|
|
4
4
|
export class LineTo extends GeometrySceneObject {
|
|
5
5
|
endPoint;
|
|
6
6
|
targetPlane;
|
|
7
|
+
_hasExplicitStart = false;
|
|
7
8
|
constructor(endPoint, targetPlane = null) {
|
|
8
9
|
super();
|
|
9
10
|
this.endPoint = endPoint;
|
|
10
11
|
this.targetPlane = targetPlane;
|
|
11
12
|
}
|
|
13
|
+
setHasExplicitStart(value = true) {
|
|
14
|
+
this._hasExplicitStart = value;
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
12
17
|
build() {
|
|
13
18
|
const plane = this.targetPlane?.getPlane() || this.sketch.getPlane();
|
|
14
19
|
const targetPoint = this.endPoint.asPoint2D();
|
|
@@ -32,7 +37,9 @@ export class LineTo extends GeometrySceneObject {
|
|
|
32
37
|
}
|
|
33
38
|
createCopy(remap) {
|
|
34
39
|
const targetPlane = this.targetPlane ? (remap.get(this.targetPlane) || this.targetPlane) : null;
|
|
35
|
-
|
|
40
|
+
const copy = new LineTo(this.endPoint, targetPlane);
|
|
41
|
+
copy._hasExplicitStart = this._hasExplicitStart;
|
|
42
|
+
return copy;
|
|
36
43
|
}
|
|
37
44
|
compareTo(other) {
|
|
38
45
|
if (!(other instanceof LineTo)) {
|
|
@@ -47,7 +54,7 @@ export class LineTo extends GeometrySceneObject {
|
|
|
47
54
|
if (this.targetPlane && other.targetPlane && !this.targetPlane.compareTo(other.targetPlane)) {
|
|
48
55
|
return false;
|
|
49
56
|
}
|
|
50
|
-
return this.endPoint.compareTo(other.endPoint);
|
|
57
|
+
return this.endPoint.compareTo(other.endPoint) && this._hasExplicitStart === other._hasExplicitStart;
|
|
51
58
|
}
|
|
52
59
|
getType() {
|
|
53
60
|
return 'line';
|
|
@@ -57,7 +64,8 @@ export class LineTo extends GeometrySceneObject {
|
|
|
57
64
|
}
|
|
58
65
|
serialize() {
|
|
59
66
|
return {
|
|
60
|
-
end: this.endPoint
|
|
67
|
+
end: this.endPoint,
|
|
68
|
+
hasExplicitStart: this._hasExplicitStart,
|
|
61
69
|
};
|
|
62
70
|
}
|
|
63
71
|
}
|
|
@@ -87,7 +87,11 @@ export class Sketch extends SceneObject {
|
|
|
87
87
|
if (pos) {
|
|
88
88
|
if (remaining === 0) {
|
|
89
89
|
for (let j = i; j >= 0; j--) {
|
|
90
|
-
const
|
|
90
|
+
const prev = previous[j];
|
|
91
|
+
if (!(prev instanceof GeometrySceneObject)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const t = prev.getTangent();
|
|
91
95
|
if (t) {
|
|
92
96
|
return { position: pos, tangent: t };
|
|
93
97
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { SceneObject } from "../../common/scene-object.js";
|
|
2
2
|
import { PlaneObjectBase } from "../plane-renderable-base.js";
|
|
3
3
|
import { ExtrudableGeometryBase } from "./extrudable-base.js";
|
|
4
|
+
import { LazyVertex } from "../lazy-vertex.js";
|
|
4
5
|
import { ISlot } from "../../core/interfaces.js";
|
|
5
6
|
export declare class Slot extends ExtrudableGeometryBase implements ISlot {
|
|
6
7
|
distance: number;
|
|
7
8
|
radius: number;
|
|
8
9
|
private _center;
|
|
9
10
|
private _angle;
|
|
11
|
+
private _startPoint;
|
|
12
|
+
private _endPoint;
|
|
10
13
|
constructor(distance: number, radius: number, targetPlane?: PlaneObjectBase);
|
|
14
|
+
static fromTwoPoints(start: LazyVertex, end: LazyVertex, radius: number, targetPlane?: PlaneObjectBase | null): Slot;
|
|
11
15
|
centered(value?: boolean): this;
|
|
12
16
|
rotate(angle: number): this;
|
|
13
17
|
build(): void;
|
|
@@ -20,5 +24,6 @@ export declare class Slot extends ExtrudableGeometryBase implements ISlot {
|
|
|
20
24
|
radius: number;
|
|
21
25
|
centered: boolean;
|
|
22
26
|
angle: number;
|
|
27
|
+
hasTwoPoints: boolean;
|
|
23
28
|
};
|
|
24
29
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Point2D } from "../../math/point.js";
|
|
2
2
|
import { Geometry } from "../../oc/geometry.js";
|
|
3
|
+
import { Vertex } from "../../common/vertex.js";
|
|
3
4
|
import { rad } from "../../helpers/math-helpers.js";
|
|
4
5
|
import { ExtrudableGeometryBase } from "./extrudable-base.js";
|
|
5
6
|
export class Slot extends ExtrudableGeometryBase {
|
|
@@ -7,11 +8,19 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
7
8
|
radius;
|
|
8
9
|
_center = false;
|
|
9
10
|
_angle = 0;
|
|
11
|
+
_startPoint = null;
|
|
12
|
+
_endPoint = null;
|
|
10
13
|
constructor(distance, radius, targetPlane = null) {
|
|
11
14
|
super(targetPlane);
|
|
12
15
|
this.distance = distance;
|
|
13
16
|
this.radius = radius;
|
|
14
17
|
}
|
|
18
|
+
static fromTwoPoints(start, end, radius, targetPlane = null) {
|
|
19
|
+
const slot = new Slot(0, radius, targetPlane);
|
|
20
|
+
slot._startPoint = start;
|
|
21
|
+
slot._endPoint = end;
|
|
22
|
+
return slot;
|
|
23
|
+
}
|
|
15
24
|
centered(value = true) {
|
|
16
25
|
this._center = value;
|
|
17
26
|
return this;
|
|
@@ -21,21 +30,28 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
21
30
|
return this;
|
|
22
31
|
}
|
|
23
32
|
build() {
|
|
24
|
-
if (this.
|
|
25
|
-
|
|
33
|
+
if (this._startPoint && this._endPoint) {
|
|
34
|
+
const s = this._startPoint.asPoint2D();
|
|
35
|
+
const e = this._endPoint.asPoint2D();
|
|
36
|
+
const dx = e.x - s.x;
|
|
37
|
+
const dy = e.y - s.y;
|
|
38
|
+
this.distance = Math.sqrt(dx * dx + dy * dy);
|
|
39
|
+
this._angle = Math.atan2(dy, dx) * 180 / Math.PI;
|
|
26
40
|
}
|
|
41
|
+
const absDistance = Math.abs(this.distance);
|
|
42
|
+
const flipAngle = this.distance < 0 ? 180 : 0;
|
|
27
43
|
const plane = this.targetPlane?.getPlane() || this.getParent().getPlane();
|
|
28
44
|
const localToWorld = plane.localToWorld.bind(plane);
|
|
29
45
|
let leftCenter = this.targetPlane
|
|
30
46
|
? plane.worldToLocal(this.targetPlane.getPlaneCenter())
|
|
31
47
|
: this.getCurrentPosition();
|
|
32
48
|
if (this._center) {
|
|
33
|
-
const angleRad = rad(this._angle);
|
|
49
|
+
const angleRad = rad(this._angle + flipAngle);
|
|
34
50
|
const cos = Math.cos(angleRad);
|
|
35
51
|
const sin = Math.sin(angleRad);
|
|
36
|
-
leftCenter = leftCenter.translate(-
|
|
52
|
+
leftCenter = leftCenter.translate(-absDistance / 2 * cos, -absDistance / 2 * sin);
|
|
37
53
|
}
|
|
38
|
-
const angleRad = rad(this._angle);
|
|
54
|
+
const angleRad = rad(this._angle + flipAngle);
|
|
39
55
|
const cos = Math.cos(angleRad);
|
|
40
56
|
const sin = Math.sin(angleRad);
|
|
41
57
|
// Direction along the slot axis
|
|
@@ -44,7 +60,7 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
44
60
|
// Perpendicular direction (90 degrees CCW)
|
|
45
61
|
const perpX = -sin;
|
|
46
62
|
const perpY = cos;
|
|
47
|
-
const rightCenter = new Point2D(leftCenter.x +
|
|
63
|
+
const rightCenter = new Point2D(leftCenter.x + absDistance * dirX, leftCenter.y + absDistance * dirY);
|
|
48
64
|
// Four key points where lines meet arcs
|
|
49
65
|
const topLeft = new Point2D(leftCenter.x + this.radius * perpX, leftCenter.y + this.radius * perpY);
|
|
50
66
|
const topRight = new Point2D(rightCenter.x + this.radius * perpX, rightCenter.y + this.radius * perpY);
|
|
@@ -65,6 +81,12 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
65
81
|
Geometry.makeEdgeFromCurve(leftArc),
|
|
66
82
|
];
|
|
67
83
|
this.addShapes(edges);
|
|
84
|
+
const leftCenterVertex = Vertex.fromPoint2D(leftCenter);
|
|
85
|
+
leftCenterVertex.markAsMetaShape();
|
|
86
|
+
this.addShape(leftCenterVertex);
|
|
87
|
+
const rightCenterVertex = Vertex.fromPoint2D(rightCenter);
|
|
88
|
+
rightCenterVertex.markAsMetaShape();
|
|
89
|
+
this.addShape(rightCenterVertex);
|
|
68
90
|
if (this.sketch) {
|
|
69
91
|
if (this._center) {
|
|
70
92
|
this.setCurrentPosition(this.getCurrentPosition());
|
|
@@ -85,7 +107,13 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
85
107
|
}
|
|
86
108
|
createCopy(remap) {
|
|
87
109
|
const targetPlane = this.targetPlane ? (remap.get(this.targetPlane) || this.targetPlane) : null;
|
|
88
|
-
|
|
110
|
+
let s;
|
|
111
|
+
if (this._startPoint && this._endPoint) {
|
|
112
|
+
s = Slot.fromTwoPoints(this._startPoint, this._endPoint, this.radius, targetPlane);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
s = new Slot(this.distance, this.radius, targetPlane);
|
|
116
|
+
}
|
|
89
117
|
s.centered(this._center);
|
|
90
118
|
s.rotate(this._angle);
|
|
91
119
|
return s;
|
|
@@ -103,6 +131,22 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
103
131
|
if (this.targetPlane && other.targetPlane && !this.targetPlane.compareTo(other.targetPlane)) {
|
|
104
132
|
return false;
|
|
105
133
|
}
|
|
134
|
+
if ((this._startPoint === null) !== (other._startPoint === null)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if ((this._endPoint === null) !== (other._endPoint === null)) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (this._startPoint && other._startPoint && !this._startPoint.compareTo(other._startPoint)) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (this._endPoint && other._endPoint && !this._endPoint.compareTo(other._endPoint)) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if (this._startPoint && this._endPoint) {
|
|
147
|
+
return this.radius === other.radius &&
|
|
148
|
+
this._center === other._center;
|
|
149
|
+
}
|
|
106
150
|
return this.distance === other.distance &&
|
|
107
151
|
this.radius === other.radius &&
|
|
108
152
|
this._center === other._center &&
|
|
@@ -114,6 +158,7 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
114
158
|
radius: this.radius,
|
|
115
159
|
centered: this._center,
|
|
116
160
|
angle: this._angle,
|
|
161
|
+
hasTwoPoints: this._startPoint !== null && this._endPoint !== null,
|
|
117
162
|
};
|
|
118
163
|
}
|
|
119
164
|
}
|
|
@@ -60,6 +60,9 @@ export class TangentArcToPointTangent extends GeometrySceneObject {
|
|
|
60
60
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
61
61
|
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
62
62
|
this.addShape(edge);
|
|
63
|
+
const centerVertex = Vertex.fromPoint2D(centerPoint);
|
|
64
|
+
centerVertex.markAsMetaShape();
|
|
65
|
+
this.addShape(centerVertex);
|
|
63
66
|
this.setCurrentPosition(targetPoint);
|
|
64
67
|
}
|
|
65
68
|
createCopy(remap) {
|
|
@@ -58,6 +58,9 @@ export class TangentArcToPoint extends GeometrySceneObject {
|
|
|
58
58
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
59
59
|
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
60
60
|
this.addShape(edge);
|
|
61
|
+
const centerVertex = Vertex.fromPoint2D(centerPoint);
|
|
62
|
+
centerVertex.markAsMetaShape();
|
|
63
|
+
this.addShape(centerVertex);
|
|
61
64
|
this.setCurrentPosition(targetPoint);
|
|
62
65
|
}
|
|
63
66
|
createCopy(remap) {
|
|
@@ -44,6 +44,9 @@ export class TangentArcWithTangent extends GeometrySceneObject {
|
|
|
44
44
|
const ty = sign * Math.cos(endAngleRad);
|
|
45
45
|
this.setTangent(new Point2D(tx, ty));
|
|
46
46
|
this.addShape(edge);
|
|
47
|
+
const centerVertex = Vertex.fromPoint2D(centerPoint);
|
|
48
|
+
centerVertex.markAsMetaShape();
|
|
49
|
+
this.addShape(centerVertex);
|
|
47
50
|
this.setCurrentPosition(endPoint);
|
|
48
51
|
}
|
|
49
52
|
createCopy(remap) {
|
|
@@ -46,6 +46,9 @@ export class TangentArc extends GeometrySceneObject {
|
|
|
46
46
|
const ty = sign * Math.cos(endAngleRad);
|
|
47
47
|
this.setTangent(new Point2D(tx, ty));
|
|
48
48
|
this.addShape(edge);
|
|
49
|
+
const centerVertex = Vertex.fromPoint2D(centerPoint);
|
|
50
|
+
centerVertex.markAsMetaShape();
|
|
51
|
+
this.addShape(centerVertex);
|
|
49
52
|
this.setCurrentPosition(endPoint);
|
|
50
53
|
}
|
|
51
54
|
createCopy(remap) {
|
|
@@ -6,8 +6,10 @@ export declare class VerticalLine extends GeometrySceneObject implements IVLine
|
|
|
6
6
|
distanceOrTarget: number | SceneObject;
|
|
7
7
|
private targetPlane;
|
|
8
8
|
private _centered;
|
|
9
|
+
private _hasExplicitStart;
|
|
9
10
|
constructor(distanceOrTarget: number | SceneObject, targetPlane?: PlaneObjectBase);
|
|
10
11
|
centered(value?: boolean): this;
|
|
12
|
+
setHasExplicitStart(value?: boolean): this;
|
|
11
13
|
build(): void;
|
|
12
14
|
getDependencies(): SceneObject[];
|
|
13
15
|
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
@@ -17,5 +19,6 @@ export declare class VerticalLine extends GeometrySceneObject implements IVLine
|
|
|
17
19
|
serialize(): {
|
|
18
20
|
distance: number;
|
|
19
21
|
centered: boolean;
|
|
22
|
+
hasExplicitStart: boolean;
|
|
20
23
|
};
|
|
21
24
|
}
|