fluidcad 0.0.33 → 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 +72 -2
- package/bin/commands/init.js +55 -0
- package/bin/commands/login.js +120 -0
- package/bin/commands/mcp.js +33 -0
- package/bin/commands/pack.js +49 -0
- package/bin/commands/publish.js +136 -0
- package/bin/commands/serve.js +77 -0
- package/bin/fluidcad.js +21 -107
- 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/scene-object.d.ts +2 -1
- package/lib/dist/common/scene-object.js +3 -2
- 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/tarc.d.ts +20 -2
- package/lib/dist/core/2d/tarc.js +24 -0
- 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 +55 -25
- 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 +72 -54
- 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.d.ts +8 -2
- package/lib/dist/features/2d/arc.js +94 -17
- package/lib/dist/features/2d/back.js +3 -2
- 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.d.ts +4 -0
- package/lib/dist/features/2d/sketch.js +25 -0
- 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-constrained.d.ts +2 -0
- package/lib/dist/features/2d/tarc-constrained.js +8 -0
- package/lib/dist/features/2d/tarc-radius-to-object.d.ts +16 -0
- package/lib/dist/features/2d/tarc-radius-to-object.js +58 -0
- package/lib/dist/features/2d/tarc-to-object.d.ts +18 -0
- package/lib/dist/features/2d/tarc-to-object.js +66 -0
- package/lib/dist/features/2d/tarc-to-point-tangent.d.ts +2 -0
- package/lib/dist/features/2d/tarc-to-point-tangent.js +6 -0
- package/lib/dist/features/2d/tarc-to-point.d.ts +2 -0
- package/lib/dist/features/2d/tarc-to-point.js +6 -0
- package/lib/dist/features/2d/tarc-with-tangent.d.ts +2 -0
- package/lib/dist/features/2d/tarc-with-tangent.js +6 -0
- package/lib/dist/features/2d/tarc.d.ts +2 -0
- package/lib/dist/features/2d/tarc.js +6 -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 +13 -3
- package/lib/dist/features/extrude-base.js +32 -3
- package/lib/dist/features/extrude-to-face.js +1 -5
- package/lib/dist/features/extrude-two-distances.js +1 -2
- package/lib/dist/features/extrude.js +1 -2
- package/lib/dist/features/mirror-feature.d.ts +3 -2
- package/lib/dist/features/mirror-feature.js +1 -1
- 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 +8 -7
- package/lib/dist/features/repeat-circular.js +7 -3
- package/lib/dist/features/repeat-linear.d.ts +9 -7
- package/lib/dist/features/repeat-linear.js +9 -3
- package/lib/dist/features/repeat-matrix.d.ts +3 -1
- package/lib/dist/features/repeat-matrix.js +7 -2
- package/lib/dist/features/shell.d.ts +4 -1
- package/lib/dist/features/shell.js +14 -3
- package/lib/dist/helpers/clone-transform.d.ts +2 -1
- package/lib/dist/index.d.ts +12 -1
- package/lib/dist/index.js +11 -4
- 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 +36 -0
- package/lib/dist/math/lazy-matrix.js +134 -0
- package/lib/dist/oc/boolean-ops.d.ts +2 -2
- package/lib/dist/oc/constraints/constraint-solver-adaptor.d.ts +5 -0
- package/lib/dist/oc/constraints/constraint-solver-adaptor.js +16 -0
- package/lib/dist/oc/constraints/constraint-solver.d.ts +4 -0
- package/lib/dist/oc/constraints/curve/curve-constraint-solver.d.ts +4 -0
- package/lib/dist/oc/constraints/curve/curve-constraint-solver.js +3 -0
- package/lib/dist/oc/constraints/geometric/geometric-constraint-solver.d.ts +6 -1
- package/lib/dist/oc/constraints/geometric/geometric-constraint-solver.js +4 -0
- package/lib/dist/oc/constraints/geometric/tangent-arc-from-point-tangent.d.ts +8 -0
- package/lib/dist/oc/constraints/geometric/tangent-arc-from-point-tangent.js +111 -0
- package/lib/dist/oc/constraints/geometric/tangent-arc-radius-to-object.d.ts +8 -0
- package/lib/dist/oc/constraints/geometric/tangent-arc-radius-to-object.js +161 -0
- package/lib/dist/oc/mesh.d.ts +9 -4
- package/lib/dist/oc/mesh.js +14 -13
- package/lib/dist/oc/shell-ops.d.ts +2 -1
- package/lib/dist/oc/shell-ops.js +5 -2
- package/lib/dist/param-registry.d.ts +34 -0
- package/lib/dist/param-registry.js +60 -0
- package/lib/dist/rendering/mesh-builder.d.ts +3 -0
- package/lib/dist/rendering/mesh-builder.js +10 -5
- package/lib/dist/rendering/render-edge.d.ts +2 -1
- package/lib/dist/rendering/render-edge.js +2 -2
- package/lib/dist/rendering/render-face.d.ts +2 -1
- package/lib/dist/rendering/render-face.js +2 -2
- package/lib/dist/rendering/render-solid.d.ts +2 -1
- package/lib/dist/rendering/render-solid.js +2 -2
- package/lib/dist/rendering/render-wire.d.ts +2 -1
- package/lib/dist/rendering/render-wire.js +2 -2
- package/lib/dist/rendering/render.d.ts +3 -0
- package/lib/dist/rendering/render.js +7 -2
- package/lib/dist/scene-manager.d.ts +4 -2
- package/lib/dist/scene-manager.js +12 -4
- package/lib/dist/tests/features/2d/arc.test.js +64 -0
- package/lib/dist/tests/features/2d/back.test.js +17 -1
- package/lib/dist/tests/features/2d/tarc.test.js +157 -0
- 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/tests/features/repeat-user-repro.test.d.ts +1 -0
- package/lib/dist/tests/features/repeat-user-repro.test.js +60 -0
- package/lib/dist/tests/features/shell.test.js +36 -0
- package/lib/dist/tests/global-setup.js +2 -1
- package/lib/dist/tests/helpers/extract-blocks.d.ts +9 -0
- package/lib/dist/tests/helpers/extract-blocks.js +56 -0
- package/lib/dist/tests/llm-docs-examples.test.d.ts +1 -0
- package/lib/dist/tests/llm-docs-examples.test.js +62 -0
- package/lib/dist/tests/setup.js +2 -1
- package/lib/dist/tsconfig.tsbuildinfo +1 -1
- package/llm-docs/.coverage-allowlist.txt +9 -0
- package/llm-docs/api/arc.md +48 -0
- package/llm-docs/api/axis.md +42 -0
- package/llm-docs/api/bezier.md +41 -0
- package/llm-docs/api/booleans.md +44 -0
- package/llm-docs/api/chamfer.md +40 -0
- package/llm-docs/api/circle.md +36 -0
- package/llm-docs/api/color.md +34 -0
- package/llm-docs/api/connect.md +41 -0
- package/llm-docs/api/constraint-qualifiers.md +48 -0
- package/llm-docs/api/copy.md +63 -0
- package/llm-docs/api/cursor-lines.md +50 -0
- package/llm-docs/api/cursor-move.md +61 -0
- package/llm-docs/api/cut.md +55 -0
- package/llm-docs/api/draft.md +36 -0
- package/llm-docs/api/edge-filter.md +57 -0
- package/llm-docs/api/ellipse.md +34 -0
- package/llm-docs/api/extrude.md +74 -0
- package/llm-docs/api/face-filter.md +61 -0
- package/llm-docs/api/fillet.md +51 -0
- package/llm-docs/api/index.json +139 -0
- package/llm-docs/api/line.md +42 -0
- package/llm-docs/api/load.md +37 -0
- package/llm-docs/api/local.md +38 -0
- package/llm-docs/api/loft.md +37 -0
- package/llm-docs/api/mirror.md +44 -0
- package/llm-docs/api/offset.md +36 -0
- package/llm-docs/api/part.md +40 -0
- package/llm-docs/api/plane.md +44 -0
- package/llm-docs/api/polygon.md +37 -0
- package/llm-docs/api/primitive-solids.md +39 -0
- package/llm-docs/api/project-intersect.md +48 -0
- package/llm-docs/api/rect.md +48 -0
- package/llm-docs/api/remove.md +32 -0
- package/llm-docs/api/repeat.md +79 -0
- package/llm-docs/api/revolve.md +38 -0
- package/llm-docs/api/rib.md +40 -0
- package/llm-docs/api/rotate.md +37 -0
- package/llm-docs/api/select.md +41 -0
- package/llm-docs/api/shell.md +41 -0
- package/llm-docs/api/sketch.md +76 -0
- package/llm-docs/api/slot.md +36 -0
- package/llm-docs/api/split-trim.md +42 -0
- package/llm-docs/api/sweep.md +43 -0
- package/llm-docs/api/tarc.md +45 -0
- package/llm-docs/api/tcircle.md +38 -0
- package/llm-docs/api/tline.md +42 -0
- package/llm-docs/api/translate.md +40 -0
- package/llm-docs/api/types/aline.md +35 -0
- package/llm-docs/api/types/arc-angles.md +29 -0
- package/llm-docs/api/types/arc-points.md +48 -0
- package/llm-docs/api/types/axis-like.md +38 -0
- package/llm-docs/api/types/axis.md +21 -0
- package/llm-docs/api/types/boolean-operation.md +50 -0
- package/llm-docs/api/types/circular-repeat-options.md +31 -0
- package/llm-docs/api/types/common.md +32 -0
- package/llm-docs/api/types/cut.md +125 -0
- package/llm-docs/api/types/draft.md +21 -0
- package/llm-docs/api/types/extrudable-geometry.md +23 -0
- package/llm-docs/api/types/extrude.md +194 -0
- package/llm-docs/api/types/geometry.md +51 -0
- package/llm-docs/api/types/hline.md +35 -0
- package/llm-docs/api/types/linear-repeat-options.md +31 -0
- package/llm-docs/api/types/loft.md +154 -0
- package/llm-docs/api/types/mirror.md +35 -0
- package/llm-docs/api/types/offset.md +31 -0
- package/llm-docs/api/types/plane-like.md +35 -0
- package/llm-docs/api/types/plane-transform-options.md +29 -0
- package/llm-docs/api/types/plane.md +21 -0
- package/llm-docs/api/types/point-like.md +22 -0
- package/llm-docs/api/types/point2dlike.md +26 -0
- package/llm-docs/api/types/polygon.md +46 -0
- package/llm-docs/api/types/rect.md +128 -0
- package/llm-docs/api/types/revolve.md +102 -0
- package/llm-docs/api/types/rib.md +133 -0
- package/llm-docs/api/types/scene-object.md +33 -0
- package/llm-docs/api/types/select.md +21 -0
- package/llm-docs/api/types/shell.md +54 -0
- package/llm-docs/api/types/slot.md +43 -0
- package/llm-docs/api/types/sweep.md +189 -0
- package/llm-docs/api/types/tangent-arc-two-objects.md +46 -0
- package/llm-docs/api/types/transformable.md +93 -0
- package/llm-docs/api/types/trim.md +27 -0
- package/llm-docs/api/types/two-objects-tangent-line.md +46 -0
- package/llm-docs/api/types/vertex.md +17 -0
- package/llm-docs/api/types/vline.md +35 -0
- package/llm-docs/concepts/coordinate-system.md +45 -0
- package/llm-docs/concepts/history-and-rollback.md +40 -0
- package/llm-docs/concepts/last-selection.md +49 -0
- package/llm-docs/concepts/scene-graph.md +37 -0
- package/llm-docs/index.json +1750 -0
- package/mcp/dist/client.d.ts +65 -0
- package/mcp/dist/client.js +255 -0
- package/mcp/dist/discovery.d.ts +11 -0
- package/mcp/dist/discovery.js +78 -0
- package/mcp/dist/docs-index.d.ts +81 -0
- package/mcp/dist/docs-index.js +261 -0
- package/mcp/dist/resources.d.ts +4 -0
- package/mcp/dist/resources.js +115 -0
- package/mcp/dist/server.d.ts +12 -0
- package/mcp/dist/server.js +502 -0
- package/mcp/dist/tools/coordination.d.ts +9 -0
- package/mcp/dist/tools/coordination.js +46 -0
- package/mcp/dist/tools/docs.d.ts +66 -0
- package/mcp/dist/tools/docs.js +122 -0
- package/mcp/dist/tools/engine.d.ts +72 -0
- package/mcp/dist/tools/engine.js +190 -0
- package/mcp/dist/tools/inspection.d.ts +75 -0
- package/mcp/dist/tools/inspection.js +121 -0
- package/mcp/dist/tools/screenshot.d.ts +63 -0
- package/mcp/dist/tools/screenshot.js +263 -0
- package/mcp/dist/tools/source.d.ts +84 -0
- package/mcp/dist/tools/source.js +434 -0
- package/mcp/dist/tools/workspaces.d.ts +13 -0
- package/mcp/dist/tools/workspaces.js +33 -0
- package/mcp/dist/types.d.ts +18 -0
- package/mcp/dist/types.js +11 -0
- package/package.json +27 -7
- package/server/dist/api.d.ts +37 -0
- package/server/dist/api.js +44 -0
- package/server/dist/code-editor.d.ts +100 -0
- package/server/dist/code-editor.js +528 -2
- package/server/dist/fluidcad-server.d.ts +118 -1
- package/server/dist/fluidcad-server.js +350 -62
- package/server/dist/global-registry.d.ts +30 -0
- package/server/dist/global-registry.js +126 -0
- 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 +175 -123
- package/server/dist/instance-file.d.ts +31 -0
- package/server/dist/instance-file.js +73 -0
- package/server/dist/lint-fluid-js.d.ts +15 -0
- package/server/dist/lint-fluid-js.js +271 -0
- 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/editor.d.ts +24 -0
- package/server/dist/routes/editor.js +44 -0
- package/server/dist/routes/export.d.ts +1 -1
- package/server/dist/routes/export.js +45 -8
- package/server/dist/routes/health.d.ts +7 -0
- package/server/dist/routes/health.js +14 -0
- package/server/dist/routes/hit-test.d.ts +3 -0
- package/server/dist/routes/hit-test.js +17 -0
- package/server/dist/routes/lint.d.ts +10 -0
- package/server/dist/routes/lint.js +28 -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/render.d.ts +33 -0
- package/server/dist/routes/render.js +34 -0
- package/server/dist/routes/scene.d.ts +5 -0
- package/server/dist/routes/scene.js +48 -0
- package/server/dist/routes/screenshot.js +68 -1
- 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 +156 -3
- 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-CFi9p7wR.js +0 -4946
- package/ui/dist/assets/index-DR7c2Qk9.css +0 -2
|
@@ -16,6 +16,8 @@ export class Arc extends GeometrySceneObject {
|
|
|
16
16
|
_bulgeRadius = 0;
|
|
17
17
|
_centerPoint = null;
|
|
18
18
|
_centered = false;
|
|
19
|
+
_clockwise = false;
|
|
20
|
+
_major = false;
|
|
19
21
|
_targetPlane;
|
|
20
22
|
constructor(targetPlane = null) {
|
|
21
23
|
super();
|
|
@@ -39,6 +41,13 @@ export class Arc extends GeometrySceneObject {
|
|
|
39
41
|
arc._endAngle = endAngle;
|
|
40
42
|
return arc;
|
|
41
43
|
}
|
|
44
|
+
static circumcenter(a, b, c) {
|
|
45
|
+
const D = 2 * (a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
|
|
46
|
+
const aa = a.x * a.x + a.y * a.y;
|
|
47
|
+
const bb = b.x * b.x + b.y * b.y;
|
|
48
|
+
const cc = c.x * c.x + c.y * c.y;
|
|
49
|
+
return new Point2D((aa * (b.y - c.y) + bb * (c.y - a.y) + cc * (a.y - b.y)) / D, (aa * (c.x - b.x) + bb * (a.x - c.x) + cc * (b.x - a.x)) / D);
|
|
50
|
+
}
|
|
42
51
|
// Chainable methods (IArc)
|
|
43
52
|
radius(value) {
|
|
44
53
|
this._bulgeRadius = value;
|
|
@@ -52,6 +61,14 @@ export class Arc extends GeometrySceneObject {
|
|
|
52
61
|
this._centered = true;
|
|
53
62
|
return this;
|
|
54
63
|
}
|
|
64
|
+
cw() {
|
|
65
|
+
this._clockwise = true;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
major() {
|
|
69
|
+
this._major = true;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
55
72
|
build() {
|
|
56
73
|
if (this._startPoint && this._endPoint) {
|
|
57
74
|
// Two explicit points: default center = current position
|
|
@@ -81,21 +98,26 @@ export class Arc extends GeometrySceneObject {
|
|
|
81
98
|
const endPt = this._endPoint.asPoint2D();
|
|
82
99
|
const centerPt = this._centerPoint
|
|
83
100
|
? this._centerPoint.asPoint2D()
|
|
84
|
-
:
|
|
101
|
+
: new Point2D((startPt.x + endPt.x) / 2, (startPt.y + endPt.y) / 2);
|
|
85
102
|
const dx = startPt.x - centerPt.x;
|
|
86
103
|
const dy = startPt.y - centerPt.y;
|
|
87
104
|
const radius = Math.sqrt(dx * dx + dy * dy);
|
|
88
105
|
const endAngle = Math.atan2(endPt.y - centerPt.y, endPt.x - centerPt.x);
|
|
106
|
+
const normal = this._clockwise ? plane.normal.negate() : plane.normal;
|
|
89
107
|
const center = plane.localToWorld(centerPt);
|
|
90
108
|
const start = plane.localToWorld(startPt);
|
|
91
109
|
const end = plane.localToWorld(endPt);
|
|
92
|
-
const arc = Geometry.makeArc(center, radius,
|
|
110
|
+
const arc = Geometry.makeArc(center, radius, normal, start, end);
|
|
93
111
|
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
94
|
-
const
|
|
95
|
-
const
|
|
112
|
+
const sign = this._clockwise ? -1 : 1;
|
|
113
|
+
const tx = sign * (-Math.sin(endAngle));
|
|
114
|
+
const ty = sign * Math.cos(endAngle);
|
|
96
115
|
this.setTangent(new Point2D(tx, ty));
|
|
97
116
|
this.setState('start', Vertex.fromPoint2D(startPt));
|
|
98
117
|
this.setState('end', Vertex.fromPoint2D(endPt));
|
|
118
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
119
|
+
centerVertex.markAsMetaShape();
|
|
120
|
+
this.addShape(centerVertex);
|
|
99
121
|
this.addShape(edge);
|
|
100
122
|
if (this.sketch) {
|
|
101
123
|
this.setCurrentPosition(endPt);
|
|
@@ -129,14 +151,19 @@ export class Arc extends GeometrySceneObject {
|
|
|
129
151
|
const center = plane.localToWorld(centerPoint);
|
|
130
152
|
const start = plane.localToWorld(startPoint);
|
|
131
153
|
const end = plane.localToWorld(targetPoint);
|
|
132
|
-
const arc =
|
|
154
|
+
const arc = this._major
|
|
155
|
+
? this.makeMajorArc(startPoint, targetPoint, centerPoint, cw, plane)
|
|
156
|
+
: Geometry.makeArc(center, r, normal, start, end);
|
|
133
157
|
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
134
|
-
const signT = cw ? -1 : 1;
|
|
158
|
+
const signT = (cw ? -1 : 1) * (this._major ? -1 : 1);
|
|
135
159
|
const endTx = signT * (-Math.sin(endAngle));
|
|
136
160
|
const endTy = signT * Math.cos(endAngle);
|
|
137
161
|
this.setTangent(new Point2D(endTx, endTy));
|
|
138
162
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
139
163
|
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
164
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
165
|
+
centerVertex.markAsMetaShape();
|
|
166
|
+
this.addShape(centerVertex);
|
|
140
167
|
this.addShape(edge);
|
|
141
168
|
if (this.sketch) {
|
|
142
169
|
this.setCurrentPosition(targetPoint);
|
|
@@ -172,14 +199,19 @@ export class Arc extends GeometrySceneObject {
|
|
|
172
199
|
const center = plane.localToWorld(centerPoint);
|
|
173
200
|
const start = plane.localToWorld(startPoint);
|
|
174
201
|
const end = plane.localToWorld(targetPoint);
|
|
175
|
-
const arc =
|
|
202
|
+
const arc = this._major
|
|
203
|
+
? this.makeMajorArc(startPoint, targetPoint, centerPoint, cw, plane)
|
|
204
|
+
: Geometry.makeArc(center, r, normal, start, end);
|
|
176
205
|
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
177
|
-
const signT = cw ? -1 : 1;
|
|
206
|
+
const signT = (cw ? -1 : 1) * (this._major ? -1 : 1);
|
|
178
207
|
const endTx = signT * (-Math.sin(endAngle));
|
|
179
208
|
const endTy = signT * Math.cos(endAngle);
|
|
180
209
|
this.setTangent(new Point2D(endTx, endTy));
|
|
181
210
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
182
211
|
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
212
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
213
|
+
centerVertex.markAsMetaShape();
|
|
214
|
+
this.addShape(centerVertex);
|
|
183
215
|
this.addShape(edge);
|
|
184
216
|
if (this.sketch) {
|
|
185
217
|
this.setCurrentPosition(targetPoint);
|
|
@@ -188,6 +220,24 @@ export class Arc extends GeometrySceneObject {
|
|
|
188
220
|
this._targetPlane.removeShapes(this);
|
|
189
221
|
}
|
|
190
222
|
}
|
|
223
|
+
makeMajorArc(startPoint2D, endPoint2D, centerPoint2D, cw, plane) {
|
|
224
|
+
const startAngleRad = Math.atan2(startPoint2D.y - centerPoint2D.y, startPoint2D.x - centerPoint2D.x);
|
|
225
|
+
const endAngleRad = Math.atan2(endPoint2D.y - centerPoint2D.y, endPoint2D.x - centerPoint2D.x);
|
|
226
|
+
let minorSweep = cw ? startAngleRad - endAngleRad : endAngleRad - startAngleRad;
|
|
227
|
+
if (minorSweep <= 0) {
|
|
228
|
+
minorSweep += 2 * Math.PI;
|
|
229
|
+
}
|
|
230
|
+
const midAngle = cw
|
|
231
|
+
? startAngleRad + (2 * Math.PI - minorSweep) / 2
|
|
232
|
+
: startAngleRad - (2 * Math.PI - minorSweep) / 2;
|
|
233
|
+
const r = Math.sqrt((startPoint2D.x - centerPoint2D.x) ** 2 +
|
|
234
|
+
(startPoint2D.y - centerPoint2D.y) ** 2);
|
|
235
|
+
const midPoint2D = new Point2D(centerPoint2D.x + r * Math.cos(midAngle), centerPoint2D.y + r * Math.sin(midAngle));
|
|
236
|
+
const start = plane.localToWorld(startPoint2D);
|
|
237
|
+
const mid = plane.localToWorld(midPoint2D);
|
|
238
|
+
const end = plane.localToWorld(endPoint2D);
|
|
239
|
+
return Geometry.makeArcThreePoints(start, mid, end);
|
|
240
|
+
}
|
|
191
241
|
buildWithCenter() {
|
|
192
242
|
const plane = this._targetPlane?.getPlane() || this.sketch.getPlane();
|
|
193
243
|
const startPt = this._targetPlane
|
|
@@ -195,20 +245,33 @@ export class Arc extends GeometrySceneObject {
|
|
|
195
245
|
: this.getCurrentPosition();
|
|
196
246
|
const endPt = this._endPoint.asPoint2D();
|
|
197
247
|
const centerPt = this._centerPoint.asPoint2D();
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
248
|
+
const aStart = Math.atan2(startPt.y - centerPt.y, startPt.x - centerPt.x);
|
|
249
|
+
const aEnd = Math.atan2(endPt.y - centerPt.y, endPt.x - centerPt.x);
|
|
250
|
+
let sweep = this._clockwise ? aStart - aEnd : aEnd - aStart;
|
|
251
|
+
if (sweep <= 0) {
|
|
252
|
+
sweep += 2 * Math.PI;
|
|
253
|
+
}
|
|
254
|
+
const midAngle = this._clockwise ? aStart - sweep / 2 : aStart + sweep / 2;
|
|
255
|
+
const rStart = Math.sqrt((startPt.x - centerPt.x) ** 2 + (startPt.y - centerPt.y) ** 2);
|
|
256
|
+
const rEnd = Math.sqrt((endPt.x - centerPt.x) ** 2 + (endPt.y - centerPt.y) ** 2);
|
|
257
|
+
const rMid = (rStart + rEnd) / 2;
|
|
258
|
+
const midPt = new Point2D(centerPt.x + rMid * Math.cos(midAngle), centerPt.y + rMid * Math.sin(midAngle));
|
|
259
|
+
const actualCenter = Arc.circumcenter(startPt, midPt, endPt);
|
|
260
|
+
const endAngle = Math.atan2(endPt.y - actualCenter.y, endPt.x - actualCenter.x);
|
|
203
261
|
const start = plane.localToWorld(startPt);
|
|
204
262
|
const end = plane.localToWorld(endPt);
|
|
205
|
-
const
|
|
263
|
+
const mid = plane.localToWorld(midPt);
|
|
264
|
+
const arc = Geometry.makeArcThreePoints(start, mid, end);
|
|
206
265
|
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
207
|
-
const
|
|
208
|
-
const
|
|
266
|
+
const sign = this._clockwise ? -1 : 1;
|
|
267
|
+
const tx = sign * (-Math.sin(endAngle));
|
|
268
|
+
const ty = sign * Math.cos(endAngle);
|
|
209
269
|
this.setTangent(new Point2D(tx, ty));
|
|
210
270
|
this.setState('start', Vertex.fromPoint2D(startPt));
|
|
211
271
|
this.setState('end', Vertex.fromPoint2D(endPt));
|
|
272
|
+
const centerVertex = Vertex.fromPoint(plane.localToWorld(actualCenter));
|
|
273
|
+
centerVertex.markAsMetaShape();
|
|
274
|
+
this.addShape(centerVertex);
|
|
212
275
|
this.addShape(edge);
|
|
213
276
|
if (this.sketch) {
|
|
214
277
|
this.setCurrentPosition(endPt);
|
|
@@ -254,6 +317,9 @@ export class Arc extends GeometrySceneObject {
|
|
|
254
317
|
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
255
318
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
256
319
|
this.setState('end', Vertex.fromPoint2D(endPoint));
|
|
320
|
+
const centerVertex = Vertex.fromPoint(center);
|
|
321
|
+
centerVertex.markAsMetaShape();
|
|
322
|
+
this.addShape(centerVertex);
|
|
257
323
|
const sign = cw ? -1 : 1;
|
|
258
324
|
const tx = sign * (-Math.sin(endAngleRad));
|
|
259
325
|
const ty = sign * Math.cos(endAngleRad);
|
|
@@ -286,6 +352,8 @@ export class Arc extends GeometrySceneObject {
|
|
|
286
352
|
copy._bulgeRadius = this._bulgeRadius;
|
|
287
353
|
copy._centerPoint = this._centerPoint;
|
|
288
354
|
copy._centered = this._centered;
|
|
355
|
+
copy._clockwise = this._clockwise;
|
|
356
|
+
copy._major = this._major;
|
|
289
357
|
return copy;
|
|
290
358
|
}
|
|
291
359
|
compareTo(other) {
|
|
@@ -301,6 +369,9 @@ export class Arc extends GeometrySceneObject {
|
|
|
301
369
|
if (this._targetPlane && other._targetPlane && !this._targetPlane.compareTo(other._targetPlane)) {
|
|
302
370
|
return false;
|
|
303
371
|
}
|
|
372
|
+
if (this._clockwise !== other._clockwise) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
304
375
|
if (this._endPoint && other._endPoint) {
|
|
305
376
|
if (!this._endPoint.compareTo(other._endPoint)) {
|
|
306
377
|
return false;
|
|
@@ -316,7 +387,7 @@ export class Arc extends GeometrySceneObject {
|
|
|
316
387
|
if (this._centerPoint && other._centerPoint) {
|
|
317
388
|
return this._centerPoint.compareTo(other._centerPoint);
|
|
318
389
|
}
|
|
319
|
-
return this._bulgeRadius === other._bulgeRadius;
|
|
390
|
+
return this._bulgeRadius === other._bulgeRadius && this._major === other._major;
|
|
320
391
|
}
|
|
321
392
|
if (!this._endPoint && !other._endPoint) {
|
|
322
393
|
return this._arcRadius === other._arcRadius &&
|
|
@@ -340,6 +411,12 @@ export class Arc extends GeometrySceneObject {
|
|
|
340
411
|
if (this._bulgeRadius !== 0) {
|
|
341
412
|
base.radius = this._bulgeRadius;
|
|
342
413
|
}
|
|
414
|
+
if (this._clockwise) {
|
|
415
|
+
base.clockwise = true;
|
|
416
|
+
}
|
|
417
|
+
if (this._major) {
|
|
418
|
+
base.major = true;
|
|
419
|
+
}
|
|
343
420
|
return base;
|
|
344
421
|
}
|
|
345
422
|
return {
|
|
@@ -9,8 +9,9 @@ export class Back extends GeometrySceneObject {
|
|
|
9
9
|
return 'back';
|
|
10
10
|
}
|
|
11
11
|
build() {
|
|
12
|
-
const
|
|
13
|
-
this.setCurrentPosition(
|
|
12
|
+
const { position, tangent } = this.sketch.getPreviousState(this, this.count);
|
|
13
|
+
this.setCurrentPosition(position);
|
|
14
|
+
this.setTangent(tangent);
|
|
14
15
|
}
|
|
15
16
|
getDependencies() {
|
|
16
17
|
return [];
|
|
@@ -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
|
}
|
|
@@ -15,6 +15,10 @@ export declare class Sketch extends SceneObject implements Extrudable {
|
|
|
15
15
|
getTangentAt(currentObj: GeometrySceneObject): Point2D;
|
|
16
16
|
getPositionAt(currentObj: GeometrySceneObject): Point2D;
|
|
17
17
|
getPreviousPosition(currentObj: GeometrySceneObject, count?: number): Point2D;
|
|
18
|
+
getPreviousState(currentObj: GeometrySceneObject, count?: number): {
|
|
19
|
+
position: Point2D;
|
|
20
|
+
tangent: Point2D;
|
|
21
|
+
};
|
|
18
22
|
getLastPosition(scope?: Set<SceneObject>): Point2D;
|
|
19
23
|
build(context?: BuildSceneObjectContext): void;
|
|
20
24
|
getEdges(): Edge[];
|
|
@@ -78,6 +78,31 @@ export class Sketch extends SceneObject {
|
|
|
78
78
|
}
|
|
79
79
|
return this.getStartPoint();
|
|
80
80
|
}
|
|
81
|
+
getPreviousState(currentObj, count = 1) {
|
|
82
|
+
const children = this.getChildren();
|
|
83
|
+
const previous = children.slice(0, children.indexOf(currentObj));
|
|
84
|
+
let remaining = count;
|
|
85
|
+
for (let i = previous.length - 1; i >= 0; i--) {
|
|
86
|
+
const pos = previous[i].getState('current-position');
|
|
87
|
+
if (pos) {
|
|
88
|
+
if (remaining === 0) {
|
|
89
|
+
for (let j = i; j >= 0; j--) {
|
|
90
|
+
const prev = previous[j];
|
|
91
|
+
if (!(prev instanceof GeometrySceneObject)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const t = prev.getTangent();
|
|
95
|
+
if (t) {
|
|
96
|
+
return { position: pos, tangent: t };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { position: pos, tangent: new Point2D(1, 0) };
|
|
100
|
+
}
|
|
101
|
+
remaining--;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return { position: this.getStartPoint(), tangent: new Point2D(1, 0) };
|
|
105
|
+
}
|
|
81
106
|
getLastPosition(scope) {
|
|
82
107
|
let children = this.getChildren().slice();
|
|
83
108
|
if (scope) {
|
|
@@ -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
|
}
|