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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { setupOC, render } from "../setup.js";
|
|
3
|
+
import { getSceneManager } from "../../scene-manager.js";
|
|
4
|
+
import { SceneCompare } from "../../rendering/scene-compare.js";
|
|
5
|
+
import sketch from "../../core/sketch.js";
|
|
6
|
+
import extrude from "../../core/extrude.js";
|
|
7
|
+
import axis from "../../core/axis.js";
|
|
8
|
+
import repeat from "../../core/repeat.js";
|
|
9
|
+
import sweep from "../../core/sweep.js";
|
|
10
|
+
import cut from "../../core/cut.js";
|
|
11
|
+
import remove from "../../core/remove.js";
|
|
12
|
+
import { rect, circle, vLine, tArc, tLine, slot, move, hMove } from "../../core/2d/index.js";
|
|
13
|
+
import copy from "../../core/copy.js";
|
|
14
|
+
// Regression: re-rendering a scene whose `repeat("circular", ...)` axis is an
|
|
15
|
+
// AxisFromEdge derived from a sketch line used to crash inside
|
|
16
|
+
// SceneCompare.compare with "Cannot read properties of undefined (reading
|
|
17
|
+
// 'origin')". RepeatCircular.compareTo eagerly called getAxis() on the
|
|
18
|
+
// new-scene axis source, which hadn't been built yet (compare runs pre-render).
|
|
19
|
+
describe("repeat circular cache-compare on unbuilt axis source", () => {
|
|
20
|
+
setupOC();
|
|
21
|
+
function buildScene(includeRemove) {
|
|
22
|
+
const spine = sketch("front", () => {
|
|
23
|
+
vLine(1.5);
|
|
24
|
+
tArc(-4, 45);
|
|
25
|
+
const topSegment = tLine(1.5);
|
|
26
|
+
return { topSegment };
|
|
27
|
+
}).reusable();
|
|
28
|
+
const profile = sketch("top", () => {
|
|
29
|
+
const innerPipe = circle(1.5);
|
|
30
|
+
const outerPipe = circle(2);
|
|
31
|
+
return { innerPipe, outerPipe };
|
|
32
|
+
});
|
|
33
|
+
const pipe = sweep(spine, profile.regions.outerPipe);
|
|
34
|
+
sketch("top", () => {
|
|
35
|
+
rect(3.5).centered().radius(0.5);
|
|
36
|
+
move([-2.5 / 2, -2.5 / 2]);
|
|
37
|
+
const c = circle(0.5);
|
|
38
|
+
copy("circular", [0, 0], { count: 4, angle: 360 }, c);
|
|
39
|
+
});
|
|
40
|
+
extrude(0.375);
|
|
41
|
+
sketch(pipe.endFaces(), () => {
|
|
42
|
+
circle(4);
|
|
43
|
+
});
|
|
44
|
+
const upperFlange = extrude(-0.625);
|
|
45
|
+
sweep(spine, profile.regions.innerPipe).remove();
|
|
46
|
+
const slots = sketch(upperFlange.endFaces(), () => {
|
|
47
|
+
hMove(3.25 / 2);
|
|
48
|
+
const outerSlot = slot(1, 0.75 / 2);
|
|
49
|
+
const innerSlot = slot(1, 0.45 / 2);
|
|
50
|
+
return { outerSlot, innerSlot };
|
|
51
|
+
});
|
|
52
|
+
const s1 = cut(slots.regions.innerSlot);
|
|
53
|
+
const s2 = cut(0.25, slots.regions.outerSlot);
|
|
54
|
+
const a = axis(spine.regions.topSegment);
|
|
55
|
+
repeat("circular", a, { count: 4, angle: 360 }, s1, s2);
|
|
56
|
+
if (includeRemove) {
|
|
57
|
+
remove(spine);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function currentScene() {
|
|
61
|
+
const mgr = getSceneManager();
|
|
62
|
+
if (!mgr) {
|
|
63
|
+
throw new Error("Scene manager not initialized");
|
|
64
|
+
}
|
|
65
|
+
return mgr.currentScene;
|
|
66
|
+
}
|
|
67
|
+
function startNewScene() {
|
|
68
|
+
const mgr = getSceneManager();
|
|
69
|
+
if (!mgr) {
|
|
70
|
+
throw new Error("Scene manager not initialized");
|
|
71
|
+
}
|
|
72
|
+
return mgr.startScene();
|
|
73
|
+
}
|
|
74
|
+
it("re-parsing the same script with cache compare does not throw", () => {
|
|
75
|
+
buildScene(false);
|
|
76
|
+
render();
|
|
77
|
+
const previousScene = currentScene();
|
|
78
|
+
expect(previousScene.getAllSceneObjects().some(o => o.getError())).toBe(false);
|
|
79
|
+
const newScene = startNewScene();
|
|
80
|
+
buildScene(false);
|
|
81
|
+
SceneCompare.compare(previousScene, newScene);
|
|
82
|
+
const rendered = render();
|
|
83
|
+
const errored = rendered.getAllSceneObjects().filter(o => o.getError());
|
|
84
|
+
expect(errored.map(o => `${o.getUniqueType()}: ${o.getError()}`)).toEqual([]);
|
|
85
|
+
});
|
|
86
|
+
it("appending remove(spine) after a cached render does not throw", () => {
|
|
87
|
+
buildScene(false);
|
|
88
|
+
render();
|
|
89
|
+
const previousScene = currentScene();
|
|
90
|
+
const newScene = startNewScene();
|
|
91
|
+
buildScene(true);
|
|
92
|
+
SceneCompare.compare(previousScene, newScene);
|
|
93
|
+
const rendered = render();
|
|
94
|
+
const errored = rendered.getAllSceneObjects().filter(o => o.getError());
|
|
95
|
+
expect(errored.map(o => `${o.getUniqueType()}: ${o.getError()}`)).toEqual([]);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { setupOC, render } from "../setup.js";
|
|
3
|
+
import sketch from "../../core/sketch.js";
|
|
4
|
+
import extrude from "../../core/extrude.js";
|
|
5
|
+
import axis from "../../core/axis.js";
|
|
6
|
+
import repeat from "../../core/repeat.js";
|
|
7
|
+
import sweep from "../../core/sweep.js";
|
|
8
|
+
import cut from "../../core/cut.js";
|
|
9
|
+
import { rect, circle, vLine, tArc, tLine, slot, move, hMove } from "../../core/2d/index.js";
|
|
10
|
+
import copy from "../../core/copy.js";
|
|
11
|
+
import { countShapes } from "../utils.js";
|
|
12
|
+
// Regression: a circular repeat whose axis is an AxisFromEdge derived from
|
|
13
|
+
// a sketch line, whose targets are cuts on sketch-region slots. Exercises:
|
|
14
|
+
// - LazyMatrix.rotation with an unbuilt AxisObjectBase source
|
|
15
|
+
// - Extrude.getSourceDependencies pulling the containing Sketch into the
|
|
16
|
+
// clone set so Sketch.build's clone-mode path carries shapes for cloned
|
|
17
|
+
// geometry primitives (Slot here) that would otherwise lose their
|
|
18
|
+
// Sketch parent context after clone.
|
|
19
|
+
describe("repeat circular with axis-from-sketch-line and cut-of-slot targets", () => {
|
|
20
|
+
setupOC();
|
|
21
|
+
it("renders without errors and produces the expected cut instances", () => {
|
|
22
|
+
const spine = sketch("front", () => {
|
|
23
|
+
vLine(1.5);
|
|
24
|
+
tArc(-4, 45);
|
|
25
|
+
const topSegment = tLine(1.5);
|
|
26
|
+
return { topSegment };
|
|
27
|
+
}).reusable();
|
|
28
|
+
const profile = sketch("top", () => {
|
|
29
|
+
const innerPipe = circle(1.5);
|
|
30
|
+
const outerPipe = circle(2);
|
|
31
|
+
return { innerPipe, outerPipe };
|
|
32
|
+
});
|
|
33
|
+
const pipe = sweep(spine, profile.regions.outerPipe);
|
|
34
|
+
sketch("top", () => {
|
|
35
|
+
rect(3.5).centered().radius(0.5);
|
|
36
|
+
move([-2.5 / 2, -2.5 / 2]);
|
|
37
|
+
const c = circle(0.5);
|
|
38
|
+
copy("circular", [0, 0], { count: 4, angle: 360 }, c);
|
|
39
|
+
});
|
|
40
|
+
extrude(0.375);
|
|
41
|
+
sketch(pipe.endFaces(), () => {
|
|
42
|
+
circle(4);
|
|
43
|
+
});
|
|
44
|
+
const upperFlange = extrude(-0.625);
|
|
45
|
+
sweep(spine, profile.regions.innerPipe).remove();
|
|
46
|
+
const slots = sketch(upperFlange.endFaces(), () => {
|
|
47
|
+
hMove(3.25 / 2);
|
|
48
|
+
const outerSlot = slot(1, 0.75 / 2);
|
|
49
|
+
const innerSlot = slot(1, 0.45 / 2);
|
|
50
|
+
return { outerSlot, innerSlot };
|
|
51
|
+
});
|
|
52
|
+
const s1 = cut(slots.regions.innerSlot);
|
|
53
|
+
const s2 = cut(0.25, slots.regions.outerSlot);
|
|
54
|
+
const a = axis(spine.regions.topSegment);
|
|
55
|
+
repeat("circular", a, { count: 4, angle: 360 }, s1, s2);
|
|
56
|
+
const scene = render();
|
|
57
|
+
expect(countShapes(scene)).toBeGreaterThan(0);
|
|
58
|
+
expect(scene.getAllSceneObjects().some(o => o.getError())).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -6,6 +6,7 @@ import shell from "../../core/shell.js";
|
|
|
6
6
|
import select from "../../core/select.js";
|
|
7
7
|
import cylinder from "../../core/cylinder.js";
|
|
8
8
|
import { rect } from "../../core/2d/index.js";
|
|
9
|
+
import { Shell } from "../../features/shell.js";
|
|
9
10
|
import { countShapes } from "../utils.js";
|
|
10
11
|
import { ShapeProps } from "../../oc/props.js";
|
|
11
12
|
import { face } from "../../filters/index.js";
|
|
@@ -198,6 +199,41 @@ describe("shell", () => {
|
|
|
198
199
|
expect(first.getShapes()[0].isSame(allShapes[0])).toBe(true);
|
|
199
200
|
});
|
|
200
201
|
});
|
|
202
|
+
describe("join type", () => {
|
|
203
|
+
const buildShelledBox = (apply) => {
|
|
204
|
+
sketch("xy", () => {
|
|
205
|
+
rect(100, 100);
|
|
206
|
+
});
|
|
207
|
+
extrude(50);
|
|
208
|
+
select(face().onPlane("xy", 50));
|
|
209
|
+
const s = shell(5);
|
|
210
|
+
apply(s);
|
|
211
|
+
const scene = render();
|
|
212
|
+
return scene.getAllSceneObjects()
|
|
213
|
+
.flatMap(o => o.getShapes())
|
|
214
|
+
.find(sh => sh.getType() === "solid");
|
|
215
|
+
};
|
|
216
|
+
it("should produce a valid solid with default join type (arc)", () => {
|
|
217
|
+
const solid = buildShelledBox(() => { });
|
|
218
|
+
expect(solid).toBeDefined();
|
|
219
|
+
expect(ShapeProps.getProperties(solid.getShape()).volumeMm3).toBeGreaterThan(0);
|
|
220
|
+
});
|
|
221
|
+
it("should produce a valid solid with join('intersection')", () => {
|
|
222
|
+
const solid = buildShelledBox(s => s.join('intersection'));
|
|
223
|
+
expect(solid).toBeDefined();
|
|
224
|
+
expect(ShapeProps.getProperties(solid.getShape()).volumeMm3).toBeGreaterThan(0);
|
|
225
|
+
});
|
|
226
|
+
it("should produce a valid solid with join('tangent')", () => {
|
|
227
|
+
const solid = buildShelledBox(s => s.join('tangent'));
|
|
228
|
+
expect(solid).toBeDefined();
|
|
229
|
+
expect(ShapeProps.getProperties(solid.getShape()).volumeMm3).toBeGreaterThan(0);
|
|
230
|
+
});
|
|
231
|
+
it("should treat shells with different join types as not equal", () => {
|
|
232
|
+
const a = new Shell(5);
|
|
233
|
+
const b = new Shell(5).join('intersection');
|
|
234
|
+
expect(a.compareTo(b)).toBe(false);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
201
237
|
describe("shell with multiple selections", () => {
|
|
202
238
|
it("should shell a box by removing two faces", () => {
|
|
203
239
|
sketch("xy", () => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type FluidBlock = {
|
|
2
|
+
/** Path relative to the docs root, forward-slash. */
|
|
3
|
+
file: string;
|
|
4
|
+
/** 1-based line number where the block body starts (the line after the opening fence). */
|
|
5
|
+
line: number;
|
|
6
|
+
/** Block body — no fences. */
|
|
7
|
+
block: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function extractFluidJsBlocks(docsRootRel: string): FluidBlock[];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
const FENCE_RE = /^(\s*)```([A-Za-z0-9_.-]*)\s*$/;
|
|
4
|
+
const RUNNABLE_LANGS = new Set(["fluid.js", "fluid", "fluidjs"]);
|
|
5
|
+
function listMarkdown(dir) {
|
|
6
|
+
const out = [];
|
|
7
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
8
|
+
if (entry.name.startsWith(".") || entry.name.startsWith("_")) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
const full = path.join(dir, entry.name);
|
|
12
|
+
if (entry.isDirectory()) {
|
|
13
|
+
out.push(...listMarkdown(full));
|
|
14
|
+
}
|
|
15
|
+
else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
16
|
+
out.push(full);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
function extractFromFile(file, docsRoot) {
|
|
22
|
+
const text = fs.readFileSync(file, "utf8");
|
|
23
|
+
const lines = text.split("\n");
|
|
24
|
+
const rel = path.relative(docsRoot, file).split(path.sep).join("/");
|
|
25
|
+
const blocks = [];
|
|
26
|
+
let i = 0;
|
|
27
|
+
while (i < lines.length) {
|
|
28
|
+
const openMatch = lines[i].match(FENCE_RE);
|
|
29
|
+
if (!openMatch || !RUNNABLE_LANGS.has(openMatch[2])) {
|
|
30
|
+
i++;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const startLine = i + 2;
|
|
34
|
+
const body = [];
|
|
35
|
+
i++;
|
|
36
|
+
while (i < lines.length) {
|
|
37
|
+
const closeMatch = lines[i].match(FENCE_RE);
|
|
38
|
+
if (closeMatch && closeMatch[2] === "") {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
body.push(lines[i]);
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
blocks.push({ file: rel, line: startLine, block: body.join("\n") });
|
|
45
|
+
i++;
|
|
46
|
+
}
|
|
47
|
+
return blocks;
|
|
48
|
+
}
|
|
49
|
+
export function extractFluidJsBlocks(docsRootRel) {
|
|
50
|
+
const docsRoot = path.resolve(docsRootRel);
|
|
51
|
+
const blocks = [];
|
|
52
|
+
for (const file of listMarkdown(docsRoot).sort()) {
|
|
53
|
+
blocks.push(...extractFromFile(file, docsRoot));
|
|
54
|
+
}
|
|
55
|
+
return blocks;
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Runs every fluid.js fenced block in llm-docs/**/*.md against the real
|
|
2
|
+
// FluidCAD runtime and asserts the scene compiles and produces ≥1 rendered
|
|
3
|
+
// object. Catches three classes of doc rot:
|
|
4
|
+
//
|
|
5
|
+
// 1. Syntax errors in examples (renamed args, dropped commas, etc.).
|
|
6
|
+
// 2. API drift — an example calls a method that no longer exists.
|
|
7
|
+
// 3. Geometry-empty examples — the snippet runs but yields nothing visible,
|
|
8
|
+
// which usually means the user-facing intent broke.
|
|
9
|
+
//
|
|
10
|
+
// The runner reuses the global OCC init from global-setup.ts and the
|
|
11
|
+
// startScene/render plumbing from setup.ts, so it sits on the same OCC
|
|
12
|
+
// initialisation the rest of the test suite uses.
|
|
13
|
+
import { describe, it, expect } from "vitest";
|
|
14
|
+
import { setupOC, render } from "./setup.js";
|
|
15
|
+
import { extractFluidJsBlocks } from "./helpers/extract-blocks.js";
|
|
16
|
+
import * as core from "../core/index.js";
|
|
17
|
+
import * as filters from "../filters/index.js";
|
|
18
|
+
import * as constraints from "../features/2d/constraints/geometry-qualifier.js";
|
|
19
|
+
import * as math from "../math/index.js";
|
|
20
|
+
import { countShapes } from "./utils.js";
|
|
21
|
+
function buildGlobals() {
|
|
22
|
+
return {
|
|
23
|
+
...core,
|
|
24
|
+
...filters,
|
|
25
|
+
...constraints,
|
|
26
|
+
...math,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// Doc examples often show the `import { foo } from "fluidcad/..."` line a
|
|
30
|
+
// real user would write at the top of a .fluid.js file. The runner injects
|
|
31
|
+
// every public export as a Function() parameter, so those imports are dead
|
|
32
|
+
// weight here — and `new Function` can't parse them anyway. Strip them out
|
|
33
|
+
// before executing.
|
|
34
|
+
const IMPORT_LINE_RE = /^\s*import\s[\s\S]*?from\s+['"][^'"]+['"]\s*;?\s*$/gm;
|
|
35
|
+
function stripImports(block) {
|
|
36
|
+
return block.replace(IMPORT_LINE_RE, "");
|
|
37
|
+
}
|
|
38
|
+
function runBlock(block, file, line) {
|
|
39
|
+
const globals = buildGlobals();
|
|
40
|
+
const paramNames = Object.keys(globals);
|
|
41
|
+
const paramValues = paramNames.map((n) => globals[n]);
|
|
42
|
+
const wrapped = `"use strict";\n${stripImports(block)}\n//# sourceURL=llm-docs/${file}:${line}`;
|
|
43
|
+
const fn = new Function(...paramNames, wrapped);
|
|
44
|
+
fn(...paramValues);
|
|
45
|
+
}
|
|
46
|
+
const blocks = extractFluidJsBlocks("llm-docs");
|
|
47
|
+
describe("llm-docs fluid.js examples", () => {
|
|
48
|
+
setupOC();
|
|
49
|
+
if (blocks.length === 0) {
|
|
50
|
+
it("found at least one fluid.js block", () => {
|
|
51
|
+
expect(blocks.length).toBeGreaterThan(0);
|
|
52
|
+
});
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
for (const { file, line, block } of blocks) {
|
|
56
|
+
it(`${file}:${line} compiles and produces ≥1 rendered object`, () => {
|
|
57
|
+
runBlock(block, file, line);
|
|
58
|
+
const scene = render();
|
|
59
|
+
expect(countShapes(scene)).toBeGreaterThan(0);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
package/lib/dist/tests/setup.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { beforeEach } from "vitest";
|
|
2
2
|
import { getSceneManager, getCurrentScene } from "../scene-manager.js";
|
|
3
3
|
import { SceneRenderer } from "../rendering/render.js";
|
|
4
|
-
|
|
4
|
+
import { DEFAULT_MESH_CONFIG } from "../oc/mesh.js";
|
|
5
|
+
const renderer = new SceneRenderer(DEFAULT_MESH_CONFIG);
|
|
5
6
|
export function setupOC() {
|
|
6
7
|
beforeEach(() => {
|
|
7
8
|
getSceneManager().startScene();
|