fluidcad 0.0.32 → 0.0.34
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 +3 -2
- package/bin/commands/init.js +55 -0
- package/bin/commands/mcp.js +33 -0
- package/bin/commands/serve.js +77 -0
- package/bin/fluidcad.js +15 -107
- package/lib/dist/common/scene-object.d.ts +4 -1
- package/lib/dist/common/scene-object.js +9 -2
- package/lib/dist/common/solid.d.ts +4 -1
- package/lib/dist/common/solid.js +13 -0
- package/lib/dist/core/2d/tarc.d.ts +20 -2
- package/lib/dist/core/2d/tarc.js +24 -0
- package/lib/dist/core/index.d.ts +2 -1
- package/lib/dist/core/index.js +1 -0
- package/lib/dist/core/interfaces.d.ts +107 -2
- package/lib/dist/core/load.d.ts +2 -2
- package/lib/dist/core/repeat.js +62 -46
- package/lib/dist/core/rib.d.ts +18 -0
- package/lib/dist/core/rib.js +37 -0
- 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/sketch.d.ts +4 -0
- package/lib/dist/features/2d/sketch.js +21 -0
- 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 +3 -0
- package/lib/dist/features/2d/tarc-to-point.d.ts +2 -0
- package/lib/dist/features/2d/tarc-to-point.js +3 -0
- package/lib/dist/features/2d/tarc-with-tangent.d.ts +2 -0
- package/lib/dist/features/2d/tarc-with-tangent.js +3 -0
- package/lib/dist/features/2d/tarc.d.ts +2 -0
- package/lib/dist/features/2d/tarc.js +3 -0
- package/lib/dist/features/extrude-base.d.ts +9 -0
- package/lib/dist/features/extrude-base.js +22 -0
- 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/load.d.ts +6 -0
- package/lib/dist/features/load.js +53 -1
- package/lib/dist/features/mirror-feature.d.ts +3 -2
- package/lib/dist/features/mirror-feature.js +1 -1
- package/lib/dist/features/repeat-circular.d.ts +3 -3
- package/lib/dist/features/repeat-circular.js +8 -1
- package/lib/dist/features/repeat-linear.d.ts +4 -2
- package/lib/dist/features/repeat-linear.js +10 -1
- package/lib/dist/features/repeat-matrix.d.ts +3 -1
- package/lib/dist/features/repeat-matrix.js +7 -2
- package/lib/dist/features/rib.d.ts +31 -0
- package/lib/dist/features/rib.js +321 -0
- package/lib/dist/features/select.d.ts +1 -0
- package/lib/dist/features/select.js +81 -10
- package/lib/dist/features/shell.d.ts +4 -1
- package/lib/dist/features/shell.js +14 -3
- package/lib/dist/filters/edge/belongs-to-face.d.ts +12 -9
- package/lib/dist/filters/edge/belongs-to-face.js +64 -15
- package/lib/dist/filters/filter-builder-base.d.ts +25 -0
- package/lib/dist/filters/filter-builder-base.js +47 -0
- package/lib/dist/filters/filter.js +39 -14
- package/lib/dist/filters/from-object.d.ts +4 -0
- package/lib/dist/filters/from-object.js +10 -0
- package/lib/dist/helpers/clone-transform.d.ts +2 -1
- package/lib/dist/helpers/scene-helpers.d.ts +1 -1
- package/lib/dist/helpers/scene-helpers.js +146 -12
- package/lib/dist/index.d.ts +7 -1
- package/lib/dist/index.js +3 -3
- package/lib/dist/io/file-import.d.ts +5 -1
- package/lib/dist/io/file-import.js +29 -18
- package/lib/dist/math/lazy-matrix.d.ts +31 -0
- package/lib/dist/math/lazy-matrix.js +66 -0
- package/lib/dist/oc/color-transfer.d.ts +19 -8
- package/lib/dist/oc/color-transfer.js +70 -12
- 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/extrude-ops.d.ts +2 -1
- package/lib/dist/oc/extrude-ops.js +51 -2
- package/lib/dist/oc/mesh.d.ts +9 -4
- package/lib/dist/oc/mesh.js +14 -13
- package/lib/dist/oc/rib-ops.d.ts +35 -0
- package/lib/dist/oc/rib-ops.js +619 -0
- package/lib/dist/oc/shell-ops.d.ts +2 -1
- package/lib/dist/oc/shell-ops.js +5 -2
- package/lib/dist/oc/topology-index.d.ts +6 -0
- package/lib/dist/oc/topology-index.js +36 -0
- package/lib/dist/rendering/mesh-builder.d.ts +3 -0
- package/lib/dist/rendering/mesh-builder.js +8 -4
- 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 +3 -5
- 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 +4 -0
- package/lib/dist/rendering/render.js +50 -2
- package/lib/dist/rendering/scene-compare.js +3 -0
- package/lib/dist/rendering/scene.d.ts +1 -0
- package/lib/dist/rendering/scene.js +4 -0
- 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/color-lineage.test.js +18 -0
- package/lib/dist/tests/features/filter-positional.test.d.ts +1 -0
- package/lib/dist/tests/features/filter-positional.test.js +129 -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/rib.test.d.ts +1 -0
- package/lib/dist/tests/features/rib.test.js +598 -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/scene-compare.test.d.ts +1 -0
- package/lib/dist/tests/scene-compare.test.js +77 -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 +42 -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 +64 -0
- package/mcp/dist/client.js +248 -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 +489 -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 +56 -0
- package/mcp/dist/tools/engine.js +145 -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 +19 -5
- package/server/dist/code-editor.d.ts +36 -0
- package/server/dist/code-editor.js +8 -0
- package/server/dist/fluidcad-server.d.ts +50 -0
- package/server/dist/fluidcad-server.js +153 -1
- package/server/dist/global-registry.d.ts +30 -0
- package/server/dist/global-registry.js +126 -0
- package/server/dist/index.js +171 -26
- 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/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/lint.d.ts +10 -0
- package/server/dist/routes/lint.js +28 -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/ws-protocol.d.ts +56 -2
- package/ui/dist/assets/{index-DMw0OYCF.js → index-BdqrMDRu.js} +30 -30
- package/ui/dist/index.html +1 -1
|
@@ -19,6 +19,25 @@ export interface ISceneObject {
|
|
|
19
19
|
*/
|
|
20
20
|
reusable(): this;
|
|
21
21
|
}
|
|
22
|
+
export interface ILoadFile extends ISceneObject {
|
|
23
|
+
/**
|
|
24
|
+
* Skip applying colors from the imported file's color metadata sidecar.
|
|
25
|
+
*/
|
|
26
|
+
noColors(): this;
|
|
27
|
+
/**
|
|
28
|
+
* Keep only the solids at the given 0-based indices (in load order).
|
|
29
|
+
* Combined with {@link exclude} by applying include first, then exclude.
|
|
30
|
+
* Repeated calls accumulate.
|
|
31
|
+
* @param indices - The 0-based solid indices to keep.
|
|
32
|
+
*/
|
|
33
|
+
include(...indices: number[]): this;
|
|
34
|
+
/**
|
|
35
|
+
* Drop the solids at the given 0-based indices. Applied after {@link include}.
|
|
36
|
+
* Repeated calls accumulate.
|
|
37
|
+
* @param indices - The 0-based solid indices to drop.
|
|
38
|
+
*/
|
|
39
|
+
exclude(...indices: number[]): this;
|
|
40
|
+
}
|
|
22
41
|
export interface IBooleanOperation extends ISceneObject {
|
|
23
42
|
/**
|
|
24
43
|
* Additive boolean operation — fuses the result with all intersecting scene objects.
|
|
@@ -138,13 +157,27 @@ export interface IArcPoints extends IExtrudableGeometry {
|
|
|
138
157
|
* Positive = CCW, negative = CW.
|
|
139
158
|
* @param value - The bulge radius.
|
|
140
159
|
*/
|
|
141
|
-
radius(value: number):
|
|
160
|
+
radius(value: number): IArcRadius;
|
|
142
161
|
/**
|
|
143
162
|
* Specifies the circle center point for the arc.
|
|
144
163
|
* Mutually exclusive with `.radius()`.
|
|
145
164
|
* @param value - The center point of the arc's circle.
|
|
146
165
|
*/
|
|
147
|
-
center(value: Point2DLike):
|
|
166
|
+
center(value: Point2DLike): IArcCenter;
|
|
167
|
+
}
|
|
168
|
+
export interface IArcRadius extends IExtrudableGeometry {
|
|
169
|
+
/**
|
|
170
|
+
* Switches to the major arc (> 180°).
|
|
171
|
+
* By default, `.radius()` produces the minor arc (< 180°);
|
|
172
|
+
* `.major()` switches to the complementary major arc on the same circle.
|
|
173
|
+
*/
|
|
174
|
+
major(): this;
|
|
175
|
+
}
|
|
176
|
+
export interface IArcCenter extends IExtrudableGeometry {
|
|
177
|
+
/**
|
|
178
|
+
* Sweeps the arc clockwise from start to end instead of the default counter-clockwise.
|
|
179
|
+
*/
|
|
180
|
+
cw(): this;
|
|
148
181
|
}
|
|
149
182
|
export interface IArcAngles extends IExtrudableGeometry {
|
|
150
183
|
/**
|
|
@@ -279,6 +312,14 @@ export interface ITwoObjectsTangentLine extends IGeometry {
|
|
|
279
312
|
*/
|
|
280
313
|
end(index?: number): LazyVertex;
|
|
281
314
|
}
|
|
315
|
+
export interface ITangentArcToObject extends IGeometry {
|
|
316
|
+
/**
|
|
317
|
+
* Flips the arc to the opposite side of the start tangent. By default,
|
|
318
|
+
* the arc curves to the left of the current tangent direction;
|
|
319
|
+
* `.flip()` switches it to the right.
|
|
320
|
+
*/
|
|
321
|
+
flip(): this;
|
|
322
|
+
}
|
|
282
323
|
export interface ITangentArcTwoObjects extends IGeometry {
|
|
283
324
|
/**
|
|
284
325
|
* Returns the start vertex of the tangent arc.
|
|
@@ -695,6 +736,64 @@ export interface IRotate extends ISceneObject {
|
|
|
695
736
|
}
|
|
696
737
|
export interface IDraft extends ISceneObject {
|
|
697
738
|
}
|
|
739
|
+
export interface IRib extends IBooleanOperation {
|
|
740
|
+
/**
|
|
741
|
+
* Selects faces at the start (base) of the rib — the profile face at the sketch plane.
|
|
742
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
743
|
+
*/
|
|
744
|
+
startFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
745
|
+
/**
|
|
746
|
+
* Selects faces at the end (top) of the rib — where the rib meets the boundary.
|
|
747
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
748
|
+
*/
|
|
749
|
+
endFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
750
|
+
/**
|
|
751
|
+
* Selects the lateral wall faces of the rib.
|
|
752
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
753
|
+
*/
|
|
754
|
+
sideFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
755
|
+
/**
|
|
756
|
+
* Selects the small cap faces at the spine endpoints.
|
|
757
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
758
|
+
*/
|
|
759
|
+
capFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
760
|
+
/**
|
|
761
|
+
* Selects edges on the start faces.
|
|
762
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
763
|
+
*/
|
|
764
|
+
startEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
765
|
+
/**
|
|
766
|
+
* Selects edges on the end faces.
|
|
767
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
768
|
+
*/
|
|
769
|
+
endEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
770
|
+
/**
|
|
771
|
+
* Selects edges on the side faces, excluding edges shared with start/end faces.
|
|
772
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
773
|
+
*/
|
|
774
|
+
sideEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
775
|
+
/**
|
|
776
|
+
* Selects edges on the cap faces.
|
|
777
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
778
|
+
*/
|
|
779
|
+
capEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
780
|
+
/**
|
|
781
|
+
* Applies a draft (taper) angle to the rib walls.
|
|
782
|
+
* @param value - A single angle for uniform draft, or a `[start, end]` tuple for asymmetric draft.
|
|
783
|
+
*/
|
|
784
|
+
draft(value: number | [number, number]): this;
|
|
785
|
+
/**
|
|
786
|
+
* Switches the extrusion direction to parallel to the sketch plane
|
|
787
|
+
* (perpendicular to the spine within the plane) instead of normal to it.
|
|
788
|
+
*/
|
|
789
|
+
parallel(): this;
|
|
790
|
+
/**
|
|
791
|
+
* Extends the rib's side faces at the spine endpoints outward to blend
|
|
792
|
+
* with the target solids' walls.
|
|
793
|
+
*/
|
|
794
|
+
extend(): this;
|
|
795
|
+
}
|
|
796
|
+
export type ShellJoinType = 'arc' | 'intersection' | 'tangent';
|
|
698
797
|
export interface IShell extends ISceneObject {
|
|
699
798
|
/**
|
|
700
799
|
* Selects the inner wall faces created by the shell operation (from thickness removal).
|
|
@@ -707,4 +806,10 @@ export interface IShell extends ISceneObject {
|
|
|
707
806
|
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
708
807
|
*/
|
|
709
808
|
internalEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
809
|
+
/**
|
|
810
|
+
* Sets the join type used at inner-wall corners.
|
|
811
|
+
* @param type - `'arc'` (default) for rounded blends, `'intersection'` for sharp corners,
|
|
812
|
+
* or `'tangent'` for tangent-continuous blends.
|
|
813
|
+
*/
|
|
814
|
+
join(type: ShellJoinType): this;
|
|
710
815
|
}
|
package/lib/dist/core/load.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ILoadFile } from "./interfaces.js";
|
|
2
2
|
interface LoadFunction {
|
|
3
3
|
/**
|
|
4
4
|
* Loads a 3D model file (STEP, STL, etc.) by filename.
|
|
5
5
|
* @param fileName - The path to the model file
|
|
6
6
|
*/
|
|
7
|
-
(fileName: string):
|
|
7
|
+
(fileName: string): ILoadFile;
|
|
8
8
|
}
|
|
9
9
|
declare const _default: LoadFunction;
|
|
10
10
|
export default _default;
|
package/lib/dist/core/repeat.js
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
import { registerBuilder } from "../index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Axis } from "../math/axis.js";
|
|
3
|
+
import { SceneObject } from "../common/scene-object.js";
|
|
3
4
|
import { Matrix4 } from "../math/matrix4.js";
|
|
5
|
+
import { LazyMatrix } from "../math/lazy-matrix.js";
|
|
4
6
|
import { rad } from "../helpers/math-helpers.js";
|
|
5
7
|
import { RepeatLinear } from "../features/repeat-linear.js";
|
|
6
8
|
import { RepeatCircular } from "../features/repeat-circular.js";
|
|
7
9
|
import { cloneWithTransform } from "../helpers/clone-transform.js";
|
|
8
|
-
import { PlaneObjectBase } from "../features/plane-renderable-base.js";
|
|
9
|
-
import { PlaneObject } from "../features/plane.js";
|
|
10
10
|
import { MirrorFeature } from "../features/mirror-feature.js";
|
|
11
11
|
import { RepeatMatrix } from "../features/repeat-matrix.js";
|
|
12
|
+
import { resolveAxis, resolvePlane } from "../helpers/resolve.js";
|
|
13
|
+
import { normalizeAxis } from "../helpers/normalize.js";
|
|
12
14
|
import { AxisObjectBase } from "../features/axis-renderable-base.js";
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a repeat axis argument to a value usable by LazyMatrix. Scene-
|
|
17
|
+
* resident sources (AxisObjectBase or an edge SceneObject) go through
|
|
18
|
+
* resolveAxis so they end up in the scene and get built before consumers.
|
|
19
|
+
* Primitive inputs (world-axis string, raw Axis) stay as concrete Axis
|
|
20
|
+
* values — no extra scene object, no rendered world-axis line.
|
|
21
|
+
*/
|
|
22
|
+
function resolveRepeatAxis(arg, context) {
|
|
23
|
+
if (arg instanceof AxisObjectBase) {
|
|
24
|
+
return arg;
|
|
25
|
+
}
|
|
26
|
+
if (arg instanceof SceneObject) {
|
|
27
|
+
return resolveAxis(arg, context);
|
|
28
|
+
}
|
|
29
|
+
if (arg instanceof Axis) {
|
|
30
|
+
return arg;
|
|
31
|
+
}
|
|
32
|
+
return normalizeAxis(arg);
|
|
33
|
+
}
|
|
13
34
|
function build(context) {
|
|
14
35
|
return (function repeat() {
|
|
15
36
|
const args = Array.from(arguments);
|
|
@@ -23,8 +44,9 @@ function build(context) {
|
|
|
23
44
|
const objects = restObjects.length > 0
|
|
24
45
|
? restObjects
|
|
25
46
|
: [context.getSceneObjects().at(-1)];
|
|
26
|
-
const
|
|
27
|
-
const
|
|
47
|
+
const lazy = LazyMatrix.of(matrix);
|
|
48
|
+
const feature = new RepeatMatrix(lazy, objects);
|
|
49
|
+
const cloned = cloneWithTransform(objects, lazy, feature);
|
|
28
50
|
context.addSceneObject(feature);
|
|
29
51
|
context.addSceneObjects(cloned);
|
|
30
52
|
return feature;
|
|
@@ -35,9 +57,9 @@ function build(context) {
|
|
|
35
57
|
const type = args[0];
|
|
36
58
|
if (type === 'linear' || type === 'circular') {
|
|
37
59
|
const axisArg = args[1];
|
|
38
|
-
const
|
|
39
|
-
? axisArg.map(a =>
|
|
40
|
-
: [
|
|
60
|
+
const axisSources = Array.isArray(axisArg)
|
|
61
|
+
? axisArg.map(a => resolveRepeatAxis(a, context))
|
|
62
|
+
: [resolveRepeatAxis(axisArg, context)];
|
|
41
63
|
const options = args[2];
|
|
42
64
|
const restObjects = args.slice(3);
|
|
43
65
|
const objects = restObjects.length > 0
|
|
@@ -51,9 +73,9 @@ function build(context) {
|
|
|
51
73
|
const lengths = 'length' in options && options.length != null
|
|
52
74
|
? (Array.isArray(options.length) ? options.length : [options.length])
|
|
53
75
|
: null;
|
|
54
|
-
const repeat = new RepeatLinear(
|
|
76
|
+
const repeat = new RepeatLinear(axisSources, options, objects);
|
|
55
77
|
const transformedObjects = [];
|
|
56
|
-
const axisOffsets =
|
|
78
|
+
const axisOffsets = axisSources.map((axis, i) => {
|
|
57
79
|
const count = counts[i] ?? counts[0];
|
|
58
80
|
const offset = offsets != null
|
|
59
81
|
? (offsets[i] ?? offsets[0])
|
|
@@ -88,19 +110,26 @@ function build(context) {
|
|
|
88
110
|
if (options.skip?.some(s => s.length === indices.length && s.every((v, i) => v === indices[i]))) {
|
|
89
111
|
continue;
|
|
90
112
|
}
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
113
|
+
// Capture per-axis offset + signed index for this instance; the
|
|
114
|
+
// axis direction is read lazily at build time so an AxisObjectBase
|
|
115
|
+
// can still be unbuilt at parse time.
|
|
116
|
+
const perAxis = axisOffsets.map((entry, a) => {
|
|
95
117
|
const idx = options.centered
|
|
96
|
-
? indices[a] - Math.floor(
|
|
118
|
+
? indices[a] - Math.floor(entry.count / 2)
|
|
97
119
|
: indices[a];
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
return { axis: entry.axis, offset: entry.offset, idx };
|
|
121
|
+
});
|
|
122
|
+
const lazy = LazyMatrix.from(() => {
|
|
123
|
+
let dx = 0, dy = 0, dz = 0;
|
|
124
|
+
for (const { axis, offset, idx } of perAxis) {
|
|
125
|
+
const dir = (axis instanceof AxisObjectBase ? axis.getAxis() : axis).direction;
|
|
126
|
+
dx += dir.x * offset * idx;
|
|
127
|
+
dy += dir.y * offset * idx;
|
|
128
|
+
dz += dir.z * offset * idx;
|
|
129
|
+
}
|
|
130
|
+
return Matrix4.fromTranslation(dx, dy, dz);
|
|
131
|
+
});
|
|
132
|
+
const cloned = cloneWithTransform(objects, lazy, repeat);
|
|
104
133
|
transformedObjects.push(...cloned);
|
|
105
134
|
}
|
|
106
135
|
context.addSceneObject(repeat);
|
|
@@ -108,7 +137,7 @@ function build(context) {
|
|
|
108
137
|
return repeat;
|
|
109
138
|
}
|
|
110
139
|
if (type === 'circular') {
|
|
111
|
-
const axis =
|
|
140
|
+
const axis = axisSources[0];
|
|
112
141
|
const circularOptions = options;
|
|
113
142
|
const { count, centered, skip } = circularOptions;
|
|
114
143
|
const repeat = new RepeatCircular(axis, circularOptions, objects);
|
|
@@ -127,8 +156,8 @@ function build(context) {
|
|
|
127
156
|
continue;
|
|
128
157
|
}
|
|
129
158
|
const angle = startOffset + offset * i;
|
|
130
|
-
const
|
|
131
|
-
const cloned = cloneWithTransform(objects,
|
|
159
|
+
const lazy = LazyMatrix.rotation(axis, rad(angle));
|
|
160
|
+
const cloned = cloneWithTransform(objects, lazy, repeat);
|
|
132
161
|
transformedObjects.push(...cloned);
|
|
133
162
|
}
|
|
134
163
|
context.addSceneObject(repeat);
|
|
@@ -142,31 +171,16 @@ function build(context) {
|
|
|
142
171
|
const targetObjects = restObjects.length > 0
|
|
143
172
|
? restObjects
|
|
144
173
|
: [context.getSceneObjects().at(-1)];
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
planeObj.build();
|
|
150
|
-
normalizedPlane = planeObj.getPlane();
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
normalizedPlane = normalizePlane(planeArg);
|
|
154
|
-
planeObj = new PlaneObject(normalizedPlane);
|
|
155
|
-
planeObj.build();
|
|
156
|
-
context.addSceneObject(planeObj);
|
|
157
|
-
}
|
|
158
|
-
const matrix = Matrix4.mirrorPlane(normalizedPlane.normal, normalizedPlane.origin);
|
|
159
|
-
const mirrorFeature = new MirrorFeature(planeObj, matrix);
|
|
160
|
-
const mirrorTree = cloneWithTransform(targetObjects, matrix, mirrorFeature);
|
|
174
|
+
const planeObj = resolvePlane(planeArg, context);
|
|
175
|
+
const lazy = LazyMatrix.mirror(planeObj);
|
|
176
|
+
const mirrorFeature = new MirrorFeature(planeObj, lazy);
|
|
177
|
+
const mirrorTree = cloneWithTransform(targetObjects, lazy, mirrorFeature);
|
|
161
178
|
context.addSceneObject(mirrorFeature);
|
|
162
179
|
context.addSceneObjects(mirrorTree);
|
|
163
180
|
return mirrorFeature;
|
|
164
181
|
}
|
|
165
182
|
if (type === 'rotate') {
|
|
166
183
|
const axisArg = args[1];
|
|
167
|
-
const axis = axisArg instanceof AxisObjectBase
|
|
168
|
-
? axisArg.getAxis()
|
|
169
|
-
: normalizeAxis(axisArg);
|
|
170
184
|
let angle = 90;
|
|
171
185
|
let restStart = 2;
|
|
172
186
|
if (typeof args[2] === 'number') {
|
|
@@ -177,9 +191,11 @@ function build(context) {
|
|
|
177
191
|
const objects = restObjects.length > 0
|
|
178
192
|
? restObjects
|
|
179
193
|
: [context.getSceneObjects().at(-1)];
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
const
|
|
194
|
+
const axis = resolveRepeatAxis(axisArg, context);
|
|
195
|
+
const lazy = LazyMatrix.rotation(axis, rad(angle));
|
|
196
|
+
const sources = axis instanceof AxisObjectBase ? [axis] : [];
|
|
197
|
+
const feature = new RepeatMatrix(lazy, objects, sources);
|
|
198
|
+
const cloned = cloneWithTransform(objects, lazy, feature);
|
|
183
199
|
context.addSceneObject(feature);
|
|
184
200
|
context.addSceneObjects(cloned);
|
|
185
201
|
return feature;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IRib, ISceneObject } from "./interfaces.js";
|
|
2
|
+
interface RibFunction {
|
|
3
|
+
/**
|
|
4
|
+
* Creates a rib from the last sketch with the given thickness.
|
|
5
|
+
* The rib extends in the sketch normal direction until it reaches
|
|
6
|
+
* surrounding solids. Positive thickness = forward, negative = reverse.
|
|
7
|
+
* @param thickness - Wall thickness (sign controls direction)
|
|
8
|
+
*/
|
|
9
|
+
(thickness: number): IRib;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a rib from an explicit sketch spine with the given thickness.
|
|
12
|
+
* @param thickness - Wall thickness (sign controls direction)
|
|
13
|
+
* @param spine - The sketch providing the rib spine wire and plane
|
|
14
|
+
*/
|
|
15
|
+
(thickness: number, spine: ISceneObject): IRib;
|
|
16
|
+
}
|
|
17
|
+
declare const _default: RibFunction;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SceneObject } from "../common/scene-object.js";
|
|
2
|
+
import { registerBuilder } from "../index.js";
|
|
3
|
+
import { Rib } from "../features/rib.js";
|
|
4
|
+
function isExtrudable(obj) {
|
|
5
|
+
return obj instanceof SceneObject && obj.isExtrudable();
|
|
6
|
+
}
|
|
7
|
+
function build(context) {
|
|
8
|
+
//@ts-ignore
|
|
9
|
+
return function rib() {
|
|
10
|
+
const args = [...arguments];
|
|
11
|
+
if (args.length === 0) {
|
|
12
|
+
throw new Error("rib() requires at least a thickness argument.");
|
|
13
|
+
}
|
|
14
|
+
const thickness = args[0];
|
|
15
|
+
if (typeof thickness !== 'number' || thickness === 0) {
|
|
16
|
+
throw new Error("rib() thickness must be a non-zero number.");
|
|
17
|
+
}
|
|
18
|
+
let spine;
|
|
19
|
+
let extrudable;
|
|
20
|
+
if (args.length > 1 && isExtrudable(args[1])) {
|
|
21
|
+
spine = args[1];
|
|
22
|
+
extrudable = args[1];
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const lastExtrudable = context.getLastExtrudable();
|
|
26
|
+
if (!lastExtrudable) {
|
|
27
|
+
throw new Error("rib() requires a sketch. No sketch found in the scene.");
|
|
28
|
+
}
|
|
29
|
+
spine = lastExtrudable;
|
|
30
|
+
extrudable = lastExtrudable;
|
|
31
|
+
}
|
|
32
|
+
const result = new Rib(thickness, spine, extrudable);
|
|
33
|
+
context.addSceneObject(result);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export default registerBuilder(build);
|
|
@@ -2,9 +2,9 @@ import { Point2DLike } from "../../math/point.js";
|
|
|
2
2
|
import { PlaneObjectBase } from "../plane-renderable-base.js";
|
|
3
3
|
import { GeometrySceneObject } from "./geometry.js";
|
|
4
4
|
import { LazyVertex } from "../lazy-vertex.js";
|
|
5
|
-
import { IArcPoints, IArcAngles } from "../../core/interfaces.js";
|
|
5
|
+
import { IArcPoints, IArcRadius, IArcCenter, IArcAngles } from "../../core/interfaces.js";
|
|
6
6
|
import { SceneObject } from "../../common/scene-object.js";
|
|
7
|
-
export declare class Arc extends GeometrySceneObject implements IArcPoints, IArcAngles {
|
|
7
|
+
export declare class Arc extends GeometrySceneObject implements IArcPoints, IArcRadius, IArcCenter, IArcAngles {
|
|
8
8
|
private _startPoint;
|
|
9
9
|
private _endPoint;
|
|
10
10
|
private _arcRadius;
|
|
@@ -13,18 +13,24 @@ export declare class Arc extends GeometrySceneObject implements IArcPoints, IArc
|
|
|
13
13
|
private _bulgeRadius;
|
|
14
14
|
private _centerPoint;
|
|
15
15
|
private _centered;
|
|
16
|
+
private _clockwise;
|
|
17
|
+
private _major;
|
|
16
18
|
private _targetPlane;
|
|
17
19
|
constructor(targetPlane?: PlaneObjectBase | null);
|
|
18
20
|
static toPoint(endPoint: LazyVertex, targetPlane?: PlaneObjectBase | null): Arc;
|
|
19
21
|
static twoPoints(startPoint: LazyVertex, endPoint: LazyVertex, targetPlane?: PlaneObjectBase | null): Arc;
|
|
20
22
|
static fromAngles(arcRadius: number, startAngle: number, endAngle: number, targetPlane?: PlaneObjectBase | null): Arc;
|
|
23
|
+
private static circumcenter;
|
|
21
24
|
radius(value: number): this;
|
|
22
25
|
center(value: Point2DLike): this;
|
|
23
26
|
centered(): this;
|
|
27
|
+
cw(): this;
|
|
28
|
+
major(): this;
|
|
24
29
|
build(): void;
|
|
25
30
|
private buildTwoPointsCenter;
|
|
26
31
|
private buildTwoPointsBulge;
|
|
27
32
|
private buildToPoint;
|
|
33
|
+
private makeMajorArc;
|
|
28
34
|
private buildWithCenter;
|
|
29
35
|
private buildFromAngles;
|
|
30
36
|
getType(): string;
|
|
@@ -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.fromPoint2D(centerPt);
|
|
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.fromPoint2D(centerPoint);
|
|
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.fromPoint2D(centerPoint);
|
|
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.fromPoint2D(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.fromPoint2D(centerPoint);
|
|
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 {
|