forgecad 0.9.14 → 0.9.15
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/LICENSE +6 -4
- package/README.md +8 -4
- package/dist/assets/{AdminPage-eWGs2K6H.js → AdminPage-CDyGUinA.js} +2 -2
- package/dist/assets/{BenchmarkPage-CTrLKfpo.js → BenchmarkPage-DfPMY_-d.js} +4 -15
- package/dist/assets/{BlogPage-5nPesyds.js → BlogPage-kF0fkdJT.js} +2 -2
- package/dist/assets/{DocsPage-C4Y3nbYc.js → DocsPage-B954L3YN.js} +9 -3
- package/dist/assets/EditorApp-Beb-IZ0y.js +14014 -0
- package/dist/assets/{EditorApp-BAnckbsk.css → EditorApp-CuDLxKqL.css} +698 -0
- package/dist/assets/{EmbedViewer-C8fB4n5U.js → EmbedViewer-C77B-TrF.js} +3 -3
- package/dist/assets/{LandingPageProofDriven-jSz0LaMM.js → LandingPageProofDriven-Cr6fXMDj.js} +35 -37
- package/dist/assets/LegalPage-BRlScr9A.css +91 -0
- package/dist/assets/LegalPage-Dzklqmmg.js +39 -0
- package/dist/assets/{PricingPage-BMedqFef.css → PricingPage-BPF6HKyO.css} +25 -0
- package/dist/assets/{PricingPage-B83B90zh.js → PricingPage-zWXkvlwl.js} +19 -19
- package/dist/assets/{SettingsPage-DY889pcu.js → SettingsPage-Bz0of4KQ.js} +2 -2
- package/dist/assets/app-CE3sYcV7.css +3890 -0
- package/dist/assets/{app-bEww1ic4.js → app-D3kDkggg.js} +2293 -946
- package/dist/assets/cli/{render-Cho2uKG_.js → render-DSY3mMQa.js} +337 -7
- package/dist/assets/{constructionHistoryWorker-HYwzJY4m.js → constructionHistoryWorker-gpDo-uH2.js} +927 -243
- package/dist/assets/{evalWorker-CjQwJSE-.js → evalWorker-CU0Ke6DP.js} +7800 -4164
- package/dist/assets/{forgecad_geometry-CH2nvuLA.js → forgecad_geometry-Dgceylq9.js} +43 -1
- package/dist/assets/forgecad_geometry_bg-dD4RNQF1.wasm +0 -0
- package/dist/assets/{inspectWorker-DeRnMVv1.js → inspectWorker-COyp8XXA.js} +927 -243
- package/dist/assets/{javascript-70-4uGcz.js → javascript-1kQXfVaz.js} +1 -1
- package/dist/assets/landing-proof-driven-DiGqdtWa.js +18 -0
- package/dist/assets/{landing-proof-driven-oFYW6mjz.css → landing-proof-driven-ORyigZ6p.css} +13 -7
- package/dist/assets/legalContent-ZfFGMmi4.js +251 -0
- package/dist/assets/{manifold-CG9Fokx-.js → manifold-BRI5prcH.js} +1 -1
- package/dist/assets/{manifold-uRzgk5O8.js → manifold-C-3h2M7p.js} +2 -2
- package/dist/assets/{manifold-rmfAcdwF.js → manifold-DNkrUWpA.js} +1 -1
- package/dist/assets/{reportWorker-4cW_ZpoS.js → reportWorker-CdBz5bNg.js} +7538 -10857
- package/dist/assets/{scalar-sampling-budget-CfDiFvh7.js → scalar-sampling-budget-wJF98aY9.js} +6935 -4331
- package/dist/assets/{scanProxyWorker-Bs2TDgLw.js → scanProxyWorker-B-9VbLIs.js} +32 -1
- package/dist/assets/{solver-DuJAO8S6.js → solver-BZ9LPTHs.js} +1 -1
- package/dist/assets/solver_bg-DAHZJ_rw.wasm +0 -0
- package/dist/assets/{targets-D6PWsv6X.js → targets-B9sGB5nB.js} +1 -1
- package/dist/assets/{vendor-react-Da3A2QmU.js → vendor-react-6j1Kke-Y.js} +6 -5
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/AI/ai-native-cad.md +50 -0
- package/dist/docs-raw/AI/usage.md +3 -12
- package/dist/docs-raw/CLI.md +30 -10
- package/dist/docs-raw/component-model.md +27 -11
- package/dist/docs-raw/generated/assembly.md +301 -212
- package/dist/docs-raw/generated/concepts.md +235 -237
- package/dist/docs-raw/generated/core.md +283 -6
- package/dist/docs-raw/generated/curves.md +274 -361
- package/dist/docs-raw/generated/lib.md +7 -1
- package/dist/docs-raw/generated/output.md +19 -4
- package/dist/docs-raw/generated/runtime-names.md +41 -0
- package/dist/docs-raw/generated/sdf.md +31 -0
- package/dist/docs-raw/generated/sheet-metal.md +9 -0
- package/dist/docs-raw/generated/sketch.md +44 -1
- package/dist/docs-raw/generated/viewport.md +11 -3
- package/dist/docs-raw/guides/coordinate-system.md +20 -16
- package/dist/docs-raw/guides/geometry-conventions.md +2 -2
- package/dist/docs-raw/guides/inspection-bundles.md +2 -1
- package/dist/docs-raw/guides/joint-design.md +24 -0
- package/dist/docs-raw/guides/positioning.md +13 -3
- package/dist/docs-raw/legal/privacy.md +63 -0
- package/dist/docs-raw/legal/software-license.md +55 -0
- package/dist/docs-raw/legal/terms.md +87 -0
- package/dist/docs-raw/skills/forgecad-3d-reconstruction.md +1 -1
- package/dist/docs-raw/skills/forgecad-blockout-model.md +1 -1
- package/dist/docs-raw/skills/forgecad-component-model.md +11 -2
- package/dist/docs-raw/skills/forgecad-high-level-spec.md +1 -1
- package/dist/docs-raw/skills/forgecad-image-replicator.md +8 -8
- package/dist/docs-raw/skills/forgecad-lld.md +1 -1
- package/dist/docs-raw/skills/forgecad-make-a-model.md +1 -1
- package/dist/docs-raw/skills/forgecad-model-grader.md +2 -2
- package/dist/docs-raw/skills/forgecad-prepare-prompt.md +2 -2
- package/dist/docs-raw/skills/forgecad-project.md +1 -1
- package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +1 -1
- package/dist/docs-raw/skills/forgecad-render-inspect.md +4 -2
- package/dist/docs-raw/skills/forgecad-visual-spec.md +1 -1
- package/dist/docs-raw/skills/forgecad.md +4 -3
- package/dist/index.html +40 -12
- package/dist/llms.txt +8 -0
- package/dist/site.webmanifest +1 -1
- package/dist/sitemap.xml +49 -13
- package/dist-cli/{check-compiler-U5SOPN7X.js → check-compiler-SDX5QIXI.js} +1 -2
- package/dist-cli/{check-query-propagation-XOKNSSYU.js → check-query-propagation-EAYEFT77.js} +1 -2
- package/dist-cli/{chunk-EXWGNL6K.js → chunk-N4O47JLF.js} +12540 -9046
- package/dist-cli/forgecad.js +1786 -679
- package/dist-cli/{forgecad_geometry-GYVNKPIE.js → forgecad_geometry-QOQIIP53.js} +42 -1
- package/dist-cli/forgecad_geometry_bg.wasm +0 -0
- package/dist-cli/{solver-46FFSK2U.js → solver-OK4HECRH.js} +0 -1
- package/dist-cli/solver_bg.wasm +0 -0
- package/dist-skill/CONTEXT.md +1117 -721
- package/dist-skill/SKILL.md +3 -2
- package/dist-skill/docs/API/core/concepts.md +64 -1
- package/dist-skill/docs/CLI.md +30 -10
- package/dist-skill/docs/generated/assembly.md +277 -229
- package/dist-skill/docs/generated/core.md +283 -6
- package/dist-skill/docs/generated/curves.md +272 -362
- package/dist-skill/docs/generated/lib.md +7 -1
- package/dist-skill/docs/generated/output.md +19 -4
- package/dist-skill/docs/generated/runtime-names.md +41 -0
- package/dist-skill/docs/generated/sdf.md +31 -0
- package/dist-skill/docs/generated/sheet-metal.md +9 -0
- package/dist-skill/docs/generated/sketch.md +44 -2
- package/dist-skill/docs/generated/viewport.md +2 -87
- package/dist-skill/docs/guides/coordinate-system.md +20 -16
- package/dist-skill/docs/guides/geometry-conventions.md +2 -2
- package/dist-skill/docs/guides/inspection-bundles.md +2 -1
- package/dist-skill/docs/guides/joint-design.md +24 -0
- package/dist-skill/docs/guides/positioning.md +13 -3
- package/dist-skill/library/forgecad-component-model/SKILL.md +10 -1
- package/dist-skill/library/forgecad-image-replicator/SKILL.md +6 -6
- package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.py +166 -0
- package/dist-skill/library/forgecad-model-grader/SKILL.md +1 -1
- package/dist-skill/library/forgecad-prepare-prompt/SKILL.md +1 -1
- package/dist-skill/library/forgecad-render-inspect/SKILL.md +3 -1
- package/examples/api/assembly-kinematics-foundation.forge.js +65 -0
- package/examples/api/assembly-kinematics-four-bar.forge.js +115 -0
- package/examples/api/assembly-kinematics-limb.forge.js +116 -0
- package/examples/api/connector-frame-rig-chain.forge.js +102 -0
- package/examples/api/exact-sheet-shell-assembly.forge.js +0 -2
- package/examples/api/exact-surface-studio.forge.js +6 -8
- package/examples/api/helix-basics.forge.js +6 -6
- package/examples/api/lean-foundations/README.md +12 -0
- package/examples/api/lean-foundations/curve-blend-exact.forge.js +22 -0
- package/examples/api/lean-foundations/curve-fit-interpolation.forge.js +18 -0
- package/examples/api/lean-foundations/curve-helix-canonicalization.forge.js +27 -0
- package/examples/api/lean-foundations/curve-route-canonicalization.forge.js +16 -0
- package/examples/api/lean-foundations/curve-trim-reverse.forge.js +24 -0
- package/examples/api/lean-foundations/exact-curve-arc.forge.js +36 -0
- package/examples/api/mixed-edge-finishes-proof.forge.js +8 -11
- package/examples/api/route3d-elbow.forge.js +68 -0
- package/examples/api/transition-curves.forge.js +44 -15
- package/examples/api/y-blend-corner-showcase.forge.js +0 -2
- package/examples/generative/coral-vase.forge.js +1 -1
- package/examples/nurbs-tube.forge.js +1 -1
- package/package.json +14 -13
- package/dist/assets/EditorApp-lXv53A1m.js +0 -13610
- package/dist/assets/app-CsHnaBWt.css +0 -1789
- package/dist/assets/forgecad_geometry_bg-C5_E9Oa9.wasm +0 -0
- package/dist/assets/solver_bg-CWvv4lnN.wasm +0 -0
- package/dist/docs-raw/API/README.md +0 -16
- package/dist/docs-raw/API/core/concepts.md +0 -118
- package/dist/docs-raw/INDEX.md +0 -138
- package/dist/docs-raw/RELEASING.md +0 -87
- package/dist/docs-raw/agent-native-api.md +0 -27
- package/dist/docs-raw/beta-deployment.md +0 -304
- package/dist/docs-raw/beta-operations.md +0 -325
- package/dist/docs-raw/blueprint-first.md +0 -145
- package/dist/docs-raw/cli-monetization.md +0 -112
- package/dist/docs-raw/coding-best-practices.md +0 -120
- package/dist/docs-raw/coding.md +0 -340
- package/dist/docs-raw/deployment.md +0 -374
- package/dist/docs-raw/guides/skill-maintenance.md +0 -161
- package/dist/docs-raw/guides/surface-members.md +0 -82
- package/dist/docs-raw/harbor-cli.md +0 -854
- package/dist/docs-raw/internals/backend-vocabulary.md +0 -35
- package/dist/docs-raw/internals/compiler.md +0 -307
- package/dist/docs-raw/internals/constraint-solver-quality.md +0 -161
- package/dist/docs-raw/internals/constraint-solver.md +0 -176
- package/dist/docs-raw/internals/shape-from-slices.md +0 -152
- package/dist/docs-raw/internals/sketch-2d-pipeline.md +0 -108
- package/dist/docs-raw/platform/admin.md +0 -45
- package/dist/docs-raw/platform/architecture.md +0 -82
- package/dist/docs-raw/platform/auth.md +0 -139
- package/dist/docs-raw/platform/email.md +0 -67
- package/dist/docs-raw/platform/google-oauth-setup.md +0 -88
- package/dist/docs-raw/platform/observability.md +0 -197
- package/dist/docs-raw/platform/projects.md +0 -111
- package/dist/docs-raw/platform/sharing.md +0 -90
- package/dist/docs-raw/product/README.md +0 -39
- package/dist/docs-raw/product/api-as-product-language.md +0 -13
- package/dist/docs-raw/product/business-model.md +0 -15
- package/dist/docs-raw/product/competitive-positioning.md +0 -17
- package/dist/docs-raw/product/creative-manufacturing.md +0 -15
- package/dist/docs-raw/product/founder-story.md +0 -11
- package/dist/docs-raw/product/manufacturing-workflows.md +0 -15
- package/dist/docs-raw/product/onboarding-first-experience.md +0 -256
- package/dist/docs-raw/product/product-loop.md +0 -17
- package/dist/docs-raw/product/strategic-decisions.md +0 -22
- package/dist/docs-raw/product/user-outreach-email-templates.md +0 -161
- package/dist/docs-raw/product/user-segments.md +0 -15
- package/dist/docs-raw/product/vision.md +0 -26
- package/dist/docs-raw/rl-environments.md +0 -350
- package/dist/docs-raw/runbook.md +0 -611
- package/dist-cli/check-compiler-U5SOPN7X.js.map +0 -1
- package/dist-cli/check-query-propagation-XOKNSSYU.js.map +0 -1
- package/dist-cli/chunk-EXWGNL6K.js.map +0 -1
- package/dist-cli/forgecad.js.map +0 -1
- package/dist-cli/forgecad_geometry-GYVNKPIE.js.map +0 -1
- package/dist-cli/solver-46FFSK2U.js.map +0 -1
- package/dist-skill/SKILL-dev.md +0 -145
- package/dist-skill/docs-dev/API/core/concepts.md +0 -118
- package/dist-skill/docs-dev/CLI.md +0 -677
- package/dist-skill/docs-dev/agent-native-api.md +0 -27
- package/dist-skill/docs-dev/blueprint-first.md +0 -145
- package/dist-skill/docs-dev/coding-best-practices.md +0 -120
- package/dist-skill/docs-dev/coding.md +0 -340
- package/dist-skill/docs-dev/component-model.md +0 -164
- package/dist-skill/docs-dev/generated/assembly.md +0 -794
- package/dist-skill/docs-dev/generated/core.md +0 -2117
- package/dist-skill/docs-dev/generated/curves.md +0 -2583
- package/dist-skill/docs-dev/generated/lib.md +0 -169
- package/dist-skill/docs-dev/generated/output.md +0 -247
- package/dist-skill/docs-dev/generated/sdf.md +0 -446
- package/dist-skill/docs-dev/generated/sheet-metal.md +0 -504
- package/dist-skill/docs-dev/generated/sketch.md +0 -1811
- package/dist-skill/docs-dev/generated/viewport.md +0 -585
- package/dist-skill/docs-dev/generated/wood.md +0 -108
- package/dist-skill/docs-dev/guides/coordinate-system.md +0 -46
- package/dist-skill/docs-dev/guides/geometry-conventions.md +0 -52
- package/dist-skill/docs-dev/guides/inspection-bundles.md +0 -485
- package/dist-skill/docs-dev/guides/joint-design.md +0 -78
- package/dist-skill/docs-dev/guides/modeling-recipes.md +0 -78
- package/dist-skill/docs-dev/guides/positioning.md +0 -161
- package/dist-skill/docs-dev/guides/skill-maintenance.md +0 -161
- package/dist-skill/docs-dev/internals/backend-vocabulary.md +0 -35
- package/dist-skill/docs-dev/internals/compiler.md +0 -307
- package/dist-skill/docs-dev/internals/constraint-solver-quality.md +0 -161
- package/dist-skill/docs-dev/internals/constraint-solver.md +0 -176
- package/dist-skill/docs-dev/internals/sketch-2d-pipeline.md +0 -108
- package/dist-skill/library/forgecad-image-replicator/scripts/compare_images.mjs +0 -289
|
@@ -7,13 +7,13 @@ Every public API function belongs to one of 16 fundamental concepts. This docume
|
|
|
7
7
|
- **[C1: Primitive Construction](#c1-primitive-construction)** — Create geometry from parameters — no input geometry required. *(76 functions)*
|
|
8
8
|
- **[C2: Boolean Combination](#c2-boolean-combination)** — Combine same-dimension geometry using CSG set operations. *(6 functions)*
|
|
9
9
|
- **[C3: Rigid Transform](#c3-rigid-transform)** — Reposition or reorient geometry without changing its shape. *(3 functions)*
|
|
10
|
-
- **[C4: Dimensional Promotion](#c4-dimensional-promotion)** — Convert a 2D profile into a 3D solid (extrude, revolve, loft, sweep). *(
|
|
10
|
+
- **[C4: Dimensional Promotion](#c4-dimensional-promotion)** — Convert a 2D profile into a 3D solid (extrude, revolve, loft, sweep). *(52 functions)*
|
|
11
11
|
- **[C5: Topology Query](#c5-topology-query)** — Select or inspect named faces and edges on a shape. *(3 functions)*
|
|
12
12
|
- **[C6: Edge Feature](#c6-edge-feature)** — Modify edges of a solid — fillets, chamfers, draft, offset. *(7 functions)*
|
|
13
13
|
- **[C7: Pattern Replication](#c7-pattern-replication)** — Duplicate geometry in regular arrangements (linear, circular, mirror). *(6 functions)*
|
|
14
14
|
- **[C8: Constraint Solving](#c8-constraint-solving)** — Define geometry by relationships and let a solver find positions. *(17 functions)*
|
|
15
15
|
- **[C9: Spatial Placement](#c9-spatial-placement)** — Position geometry relative to other geometry using semantic anchors. *(6 functions)*
|
|
16
|
-
- **[C10: Assembly & Kinematics](#c10-assembly-kinematics)** — Compose parts with joints for kinematic simulation. *(
|
|
16
|
+
- **[C10: Assembly & Kinematics](#c10-assembly-kinematics)** — Compose parts with joints for kinematic simulation. *(3 functions)*
|
|
17
17
|
- **[C11: Parameterization & UI](#c11-parameterization-ui)** — Declare user-facing controls that drive model geometry. *(7 functions)*
|
|
18
18
|
- **[C12: Dimensional Demotion](#c12-dimensional-demotion)** — Extract 2D geometry from a 3D solid (section, projection). *(3 functions)*
|
|
19
19
|
- **[C13: Export & Output](#c13-export-output)** — Convert geometry to external formats (STL, 3MF, SVG, DXF, G-code, PDF). *(5 functions)*
|
|
@@ -1002,10 +1002,182 @@ composeChain(...steps: TransformInput[]): Transform
|
|
|
1002
1002
|
|
|
1003
1003
|
Convert a 2D profile into a 3D solid (extrude, revolve, loft, sweep).
|
|
1004
1004
|
|
|
1005
|
-
#### `
|
|
1005
|
+
#### `Curve.Blend()` — Create an exact G1 blend curve between two directed endpoints.
|
|
1006
|
+
|
|
1007
|
+
The returned curve is a cubic non-rational `NurbsCurve3D`: ForgeCAD converts the endpoint positions and tangents into Bezier control points, so the curve can feed `sweep` and exact surface boundaries through the existing `nurbs` IR rather than a sampled polyline.
|
|
1008
|
+
|
|
1009
|
+
```js
|
|
1010
|
+
const rail = Curve.Blend(
|
|
1011
|
+
{ point: [0, 0, 0], tangent: [1, 0, 0], weight: 0.8 },
|
|
1012
|
+
{ point: [40, 20, 8], tangent: [0, 1, 0], weight: 0.8 },
|
|
1013
|
+
);
|
|
1014
|
+
const tube = sweep(circle2d(2), rail);
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
```ts
|
|
1018
|
+
Curve.Blend(start: CurveBlendEndpoint, end: CurveBlendEndpoint): NurbsCurve3D
|
|
1019
|
+
```
|
|
1020
|
+
|
|
1021
|
+
**`CurveBlendEndpoint`**
|
|
1022
|
+
- `point: Vec3` — Endpoint position.
|
|
1023
|
+
- `tangent: Vec3` — Tangent direction at this endpoint. Magnitude is ignored.
|
|
1024
|
+
- `weight?: number` — Tangent reach relative to the endpoint chord length. Default 1.
|
|
1025
|
+
|
|
1026
|
+
#### `Curve.BlendG2()` — Create an exact G2 blend curve between two directed endpoints.
|
|
1027
|
+
|
|
1028
|
+
This is the curvature-aware companion to `Curve.Blend()`. It returns a degree-5 non-rational `NurbsCurve3D` that matches endpoint position, tangent direction, and optional curvature/second-derivative vectors.
|
|
1029
|
+
|
|
1030
|
+
```js
|
|
1031
|
+
const rail = Curve.BlendG2(
|
|
1032
|
+
{ point: [0, 0, 0], tangent: [1, 0, 0], curvature: [0, 0.02, 0] },
|
|
1033
|
+
{ point: [50, 20, 0], tangent: [0, 1, 0], curvature: [-0.02, 0, 0] },
|
|
1034
|
+
);
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
```ts
|
|
1038
|
+
Curve.BlendG2(start: CurveBlendG2Endpoint, end: CurveBlendG2Endpoint): NurbsCurve3D
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
**`CurveBlendG2Endpoint`** extends CurveBlendEndpoint
|
|
1043
|
+
- `curvature?: Vec3` — Optional endpoint curvature/second-derivative vector. Default is zero.
|
|
1044
|
+
|
|
1045
|
+
#### `Curve.Arc()` — Create an exact circular 3D arc from start, end, and start tangent.
|
|
1046
|
+
|
|
1047
|
+
The returned curve is a rational quadratic `NurbsCurve3D`, split into stable spans when needed, so it can feed `sweep` without sampling the authoring intent away.
|
|
1048
|
+
|
|
1049
|
+
```js
|
|
1050
|
+
const rail = Curve.Arc({
|
|
1051
|
+
start: [40, 0, 0],
|
|
1052
|
+
end: [0, 40, 0],
|
|
1053
|
+
tangent: [0, 1, 0],
|
|
1054
|
+
});
|
|
1055
|
+
const tube = sweep(circle2d(2), rail);
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
```ts
|
|
1059
|
+
Curve.Arc(options: CurveArcOptions): NurbsCurve3D
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
**`CurveArcOptions`**
|
|
1063
|
+
- `start: Vec3` — Arc start point.
|
|
1064
|
+
- `end: Vec3` — Arc end point.
|
|
1065
|
+
- `tangent: Vec3` — Tangent direction at the start point. Magnitude is ignored.
|
|
1066
|
+
|
|
1067
|
+
#### `Curve.Line()` — Create an exact straight 3D NURBS line segment.
|
|
1068
|
+
|
|
1069
|
+
```js
|
|
1070
|
+
const rail = Curve.Line([0, 0, 0], [80, 0, 15]);
|
|
1071
|
+
const rib = sweep(circle2d(2), rail);
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
```ts
|
|
1075
|
+
Curve.Line(start: Vec3, end: Vec3): NurbsCurve3D
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
#### `Curve.Polyline()` — Create a polyline path as cloned 3D points.
|
|
1079
|
+
|
|
1080
|
+
Polylines are exact as route/path input to `sweep`. Use `Curve.Route` when the centerline needs bend and endpoint-frame metadata.
|
|
1081
|
+
|
|
1082
|
+
```ts
|
|
1083
|
+
Curve.Polyline(points: Vec3[]): Vec3[]
|
|
1084
|
+
```
|
|
1085
|
+
|
|
1086
|
+
#### `Curve.Spline()` — Create a smooth Catmull-Rom spline path.
|
|
1087
|
+
|
|
1088
|
+
This is a smooth sampled curve object. Use `Curve.Nurbs` when the path must preserve exact control-point and knot data.
|
|
1089
|
+
|
|
1090
|
+
```ts
|
|
1091
|
+
Curve.Spline(points: Vec3[], options?: Spline3DOptions): Curve3D
|
|
1092
|
+
```
|
|
1093
|
+
|
|
1094
|
+
**`Spline3DOptions`**
|
|
1095
|
+
- `closed?: boolean` — Closed loop (default false).
|
|
1096
|
+
- `tension?: number` — Catmull-Rom tension in [0, 1]. 0 = very round, 1 = linear-ish. Default 0.5.
|
|
1097
|
+
|
|
1098
|
+
#### `Curve.Nurbs()` — Create an exact NURBS 3D curve from control points, weights, knots, and degree.
|
|
1099
|
+
|
|
1100
|
+
```js
|
|
1101
|
+
const rail = Curve.Nurbs([[0, 0, 0], [30, 4, 12], [60, -4, 12], [90, 0, 0]]);
|
|
1102
|
+
const tube = sweep(circle2d(2), rail);
|
|
1103
|
+
```
|
|
1006
1104
|
|
|
1007
1105
|
```ts
|
|
1008
|
-
|
|
1106
|
+
Curve.Nurbs(points: Vec3[], options?: NurbsCurve3DOptions): NurbsCurve3D
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
**`NurbsCurve3DOptions`**
|
|
1110
|
+
|
|
1111
|
+
| Option | Type | Description |
|
|
1112
|
+
|--------|------|-------------|
|
|
1113
|
+
| `degree?` | `number` | Polynomial degree (default 3 = cubic). Must be ≥ 1. |
|
|
1114
|
+
| `weights?` | `number[]` | Rational weights, one per control point (default: all 1.0 = non-rational). |
|
|
1115
|
+
| `knots?` | `number[]` | Knot vector (default: uniform clamped). Must have length = controlPoints.length + degree + 1. |
|
|
1116
|
+
| `closed?` | `boolean` | Whether the curve is closed/periodic (default false). |
|
|
1117
|
+
|
|
1118
|
+
#### `Curve.Fit()` — Fit a non-rational NURBS curve that interpolates every input point.
|
|
1119
|
+
|
|
1120
|
+
This is global B-spline interpolation, not approximate curve reduction: ForgeCAD computes chord-length parameters, averaged clamped knots, solves the control points, then verifies the interpolation residual against `tolerance`.
|
|
1121
|
+
|
|
1122
|
+
```js
|
|
1123
|
+
const rail = Curve.Fit(
|
|
1124
|
+
[[0, 0, 0], [20, 8, 12], [50, -4, 18], [80, 0, 0]],
|
|
1125
|
+
{ degree: 3, tolerance: 0.001 },
|
|
1126
|
+
);
|
|
1127
|
+
const tube = sweep(circle2d(2), rail);
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
```ts
|
|
1131
|
+
Curve.Fit(points: Vec3[], options?: CurveFitOptions): NurbsCurve3D
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
**`CurveFitOptions`**
|
|
1135
|
+
- `degree?: number` — Polynomial degree. Default is cubic, reduced automatically for short point lists.
|
|
1136
|
+
- `tolerance?: number` — Maximum allowed interpolation residual in model units. Default 1e-7.
|
|
1137
|
+
|
|
1138
|
+
#### `Curve.Trim()` — Extract an exact curve segment from normalized parameter `start` to `end`.
|
|
1139
|
+
|
|
1140
|
+
`NurbsCurve3D` inputs are trimmed with exact knot insertion/subdomain extraction. Polyline point arrays are trimmed by arclength over their exact line segments. Sampled `Curve3D` splines are rejected until ForgeCAD has a tolerance-controlled rebuild path.
|
|
1141
|
+
|
|
1142
|
+
```ts
|
|
1143
|
+
Curve.Trim<T extends CurveTrimInput>(curve: T, start: number, end: number): CurveTrimOutput<T>
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
#### `Curve.Reverse()` — Reverse an exact curve without changing its geometry.
|
|
1147
|
+
|
|
1148
|
+
`NurbsCurve3D` inputs reverse control points, weights, and knots. Polyline point arrays are cloned and reversed. Sampled `Curve3D` splines are rejected until ForgeCAD has a tolerance-controlled rebuild path.
|
|
1149
|
+
|
|
1150
|
+
```ts
|
|
1151
|
+
Curve.Reverse<T extends CurveTrimInput>(curve: T): CurveTrimOutput<T>
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
#### `Curve.Route()` — Build analytic 3D line/arc routes for sweeps.
|
|
1155
|
+
|
|
1156
|
+
`Curve.Route.fromPolyline()` is the canonical route API. It returns a `Route3D` value object, preserving exact route segments, named port frames, and the lowerable `route3d` sweep compile plan.
|
|
1157
|
+
|
|
1158
|
+
```js
|
|
1159
|
+
const route = Curve.Route.fromPolyline(
|
|
1160
|
+
[[0, 0, 0], [0, 0, 50], [40, 0, 50]],
|
|
1161
|
+
{ cornerRadius: 12, startPort: 'inlet', endPort: 'outlet' },
|
|
1162
|
+
);
|
|
1163
|
+
const tube = sweep(circle2d(4), route);
|
|
1164
|
+
```
|
|
1165
|
+
|
|
1166
|
+
```ts
|
|
1167
|
+
Curve.Route: typeof Route3D
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
#### `Curve.Helix()` — Build helical paths and swept coils.
|
|
1171
|
+
|
|
1172
|
+
`Curve.Helix` is the canonical namespace for helical paths and coils. It uses the same sweep-based lowering as other curve paths.
|
|
1173
|
+
|
|
1174
|
+
```js
|
|
1175
|
+
const guide = Curve.Helix.path({ radius: 20, pitch: 6, turns: 4 });
|
|
1176
|
+
const spring = Curve.Helix.coil({ radius: 20, pitch: 6, turns: 4, wireRadius: 1 });
|
|
1177
|
+
```
|
|
1178
|
+
|
|
1179
|
+
```ts
|
|
1180
|
+
Curve.Helix: { path(options: HelixOptions): CurveHelixPath; coil: CurveHelixCoil; }
|
|
1009
1181
|
```
|
|
1010
1182
|
|
|
1011
1183
|
**`HelixOptions`**
|
|
@@ -1020,18 +1192,8 @@ Helix.path(options: HelixOptions): HelixCurve
|
|
|
1020
1192
|
| `clockwise?` | `boolean` | Reverse winding direction when viewed from +Z. |
|
|
1021
1193
|
| `samplesPerTurn?` | `number` | Point samples per turn for the metadata path. Default 32. |
|
|
1022
1194
|
|
|
1023
|
-
#### `Helix.coil()` — Create a solid helical coil by sweeping a profile through helix-local frames.
|
|
1024
|
-
|
|
1025
|
-
Overloads:
|
|
1026
|
-
|
|
1027
|
-
- `Helix.coil(options: HelixCoilOptions): Shape`
|
|
1028
|
-
- `Helix.coil(profile: Sketch, options: HelixCoilOptions): Shape`
|
|
1029
|
-
|
|
1030
1195
|
|
|
1031
|
-
|
|
1032
|
-
- `wireRadius?: number` — Radius of the circular wire profile. Required unless a custom profile is passed.
|
|
1033
|
-
- `profileSegments?: number` — Segment count for the default circular wire profile. Default 24.
|
|
1034
|
-
- `divisionsPerTurn?: number` — Sweep path samples per turn. Default 32.
|
|
1196
|
+
`CurveHelixPath`: `{ radius: number, pitch: number, turns: number, height: number, startAngle: number, clockwise: boolean }`
|
|
1035
1197
|
|
|
1036
1198
|
#### `Loft.station()` — Create a loft station from a 2D profile and an axis position.
|
|
1037
1199
|
|
|
@@ -1397,37 +1559,6 @@ Surface.Match(shape: Shape, options: { edge: "u0" | "u1" | "v0" | "v1"; target:
|
|
|
1397
1559
|
Surface.MatchEdge(shape: Shape, options: { edge: "u0" | "u1" | "v0" | "v1"; target: EdgeRef; continuity?: SurfaceContinuity; }): Shape
|
|
1398
1560
|
```
|
|
1399
1561
|
|
|
1400
|
-
#### `nurbs3d()` — Create a NURBS curve from control points.
|
|
1401
|
-
|
|
1402
|
-
With default options, creates a cubic non-rational B-spline with uniform clamped knots. Set `weights` for rational curves (exact circles, conics). Set `degree` for linear (1), quadratic (2), cubic (3), or higher-order curves.
|
|
1403
|
-
|
|
1404
|
-
```js
|
|
1405
|
-
// Simple cubic B-spline through control points
|
|
1406
|
-
const curve = nurbs3d([[0,0,0], [10,5,0], [20,-5,10], [30,0,5]]);
|
|
1407
|
-
const tube = sweep(circle(2), curve);
|
|
1408
|
-
```
|
|
1409
|
-
|
|
1410
|
-
```js
|
|
1411
|
-
// Rational quadratic — exact circular arc
|
|
1412
|
-
const arc = nurbs3d(
|
|
1413
|
-
[[10,0,0], [10,10,0], [0,10,0]],
|
|
1414
|
-
{ degree: 2, weights: [1, Math.SQRT1_2, 1] }
|
|
1415
|
-
);
|
|
1416
|
-
```
|
|
1417
|
-
|
|
1418
|
-
```ts
|
|
1419
|
-
nurbs3d(points: Vec3[], options?: NurbsCurve3DOptions): NurbsCurve3D
|
|
1420
|
-
```
|
|
1421
|
-
|
|
1422
|
-
**`NurbsCurve3DOptions`**
|
|
1423
|
-
|
|
1424
|
-
| Option | Type | Description |
|
|
1425
|
-
|--------|------|-------------|
|
|
1426
|
-
| `degree?` | `number` | Polynomial degree (default 3 = cubic). Must be ≥ 1. |
|
|
1427
|
-
| `weights?` | `number[]` | Rational weights, one per control point (default: all 1.0 = non-rational). |
|
|
1428
|
-
| `knots?` | `number[]` | Knot vector (default: uniform clamped). Must have length = controlPoints.length + degree + 1. |
|
|
1429
|
-
| `closed?` | `boolean` | Whether the curve is closed/periodic (default false). |
|
|
1430
|
-
|
|
1431
1562
|
#### `nurbsSurface()` — Create a NURBS surface from a grid of control points.
|
|
1432
1563
|
|
|
1433
1564
|
The control grid is indexed as `controlGrid[u][v]` — each row is a curve in the V direction, and columns trace curves in the U direction.
|
|
@@ -1449,73 +1580,6 @@ const surface = nurbsSurface(grid, { thickness: 2 });
|
|
|
1449
1580
|
nurbsSurface(controlGrid: Vec3[][], options?: NurbsSurfaceOptions): Shape
|
|
1450
1581
|
```
|
|
1451
1582
|
|
|
1452
|
-
#### `connectEdges()` — Create a transition surface or solid bridge between two edge segments.
|
|
1453
|
-
|
|
1454
|
-
Tangents can be inferred from neighboring geometry or supplied explicitly through `options`. This is useful for loft-like blends where you want a direct connection between two edge spans.
|
|
1455
|
-
|
|
1456
|
-
```ts
|
|
1457
|
-
connectEdges(edgeA: EdgeSegment, edgeB: EdgeSegment, options?: ConnectEdgesOptions): Shape
|
|
1458
|
-
```
|
|
1459
|
-
|
|
1460
|
-
**`EdgeSegment`**
|
|
1461
|
-
|
|
1462
|
-
| Option | Type | Description |
|
|
1463
|
-
|--------|------|-------------|
|
|
1464
|
-
| `index` | `number` | Stable index within the extraction (deterministic for a given mesh). |
|
|
1465
|
-
| `direction` | `Vec3` | Normalized direction from start → end. |
|
|
1466
|
-
| `dihedralAngle` | `number` | Dihedral angle in degrees (0 = coplanar, 180 = knife edge). |
|
|
1467
|
-
| `convex` | `boolean` | true = outside corner (convex), false = inside corner (concave). |
|
|
1468
|
-
| `normalA` | `Vec3` | Normal of first adjacent face. |
|
|
1469
|
-
| `normalB` | `Vec3` | Normal of second adjacent face (same as normalA for boundary edges). |
|
|
1470
|
-
| `boundary` | `boolean` | true if this is a boundary (unmatched) edge — unusual for closed solids. |
|
|
1471
|
-
| `start`, `end`, `midpoint`, `length` | | — |
|
|
1472
|
-
|
|
1473
|
-
**`TransitionCurveOptions`**
|
|
1474
|
-
- `weightA?: number` — Weight for the start edge. Controls tangent magnitude at the start. - 1.0 (default): balanced transition - > 1.0: curve follows start edge longer before turning - < 1.0: curve turns sooner at the start
|
|
1475
|
-
- `weightB?: number` — Weight for the end edge. Controls tangent magnitude at the end. - 1.0 (default): balanced transition - > 1.0: curve follows end edge longer before turning - < 1.0: curve turns sooner at the end
|
|
1476
|
-
- `samples?: number` — Number of sample points for the output polyline. Default 64. Higher values give smoother curves at the cost of more geometry.
|
|
1477
|
-
|
|
1478
|
-
**`TransitionSurfaceOptions`** extends TransitionCurveOptions
|
|
1479
|
-
|
|
1480
|
-
| Option | Type | Description |
|
|
1481
|
-
|--------|------|-------------|
|
|
1482
|
-
| `profile?` | `Sketch` | Cross-section profile to sweep along the transition curve. If omitted, a circular profile with `radius` is used. |
|
|
1483
|
-
| `radius?` | `number` | Radius of circular cross-section (used when `profile` is omitted). Default: 5% of chord length. |
|
|
1484
|
-
| `rectangleSection?` | `{ width: number; height: number; }` | Width and height for rectangular cross-section. Alternative to `radius` when `profile` is omitted. |
|
|
1485
|
-
| `up?` | `Vec3` | Preferred up vector for the sweep frame. Default: auto-detected. |
|
|
1486
|
-
| `edgeLength?` | `number` | Edge length for level-set meshing. Smaller = finer. |
|
|
1487
|
-
| `boundsPadding?` | `number` | Extra bounds padding for level-set meshing. |
|
|
1488
|
-
|
|
1489
|
-
**`ConnectEdgesOptions`** extends TransitionSurfaceOptions
|
|
1490
|
-
|
|
1491
|
-
| Option | Type | Description |
|
|
1492
|
-
|--------|------|-------------|
|
|
1493
|
-
| `endA?` | `EdgeEnd` | Which end of edge A to connect. Default: 'start'. |
|
|
1494
|
-
| `endB?` | `EdgeEnd` | Which end of edge B to connect. Default: 'start'. |
|
|
1495
|
-
| `tangentModeA?` | `TangentMode` | Tangent mode for edge A. Default: 'along'. |
|
|
1496
|
-
| `tangentModeB?` | `TangentMode` | Tangent mode for edge B. Default: 'along'. |
|
|
1497
|
-
| `tangentA?` | `Vec3` | Explicit tangent for edge A. |
|
|
1498
|
-
| `tangentB?` | `Vec3` | Explicit tangent for edge B. |
|
|
1499
|
-
| `flipA?` | `boolean` | Flip tangent A. |
|
|
1500
|
-
| `flipB?` | `boolean` | Flip tangent B. |
|
|
1501
|
-
|
|
1502
|
-
#### `hermiteTransitionG2()` — Create a quintic Hermite transition curve between two edge endpoints (G2 continuity).
|
|
1503
|
-
|
|
1504
|
-
The curve starts at `a.point` tangent to `a.tangent` with curvature `a.curvature`, and ends at `b.point` tangent to `b.tangent` with curvature `b.curvature`, with smooth G2-continuous interpolation matching position, tangent, and curvature.
|
|
1505
|
-
|
|
1506
|
-
```ts
|
|
1507
|
-
hermiteTransitionG2(a: QuinticHermiteCurveEndpoint, b: QuinticHermiteCurveEndpoint): QuinticHermiteCurve3D
|
|
1508
|
-
```
|
|
1509
|
-
|
|
1510
|
-
**`QuinticHermiteCurveEndpoint`**
|
|
1511
|
-
|
|
1512
|
-
| Option | Type | Description |
|
|
1513
|
-
|--------|------|-------------|
|
|
1514
|
-
| `point` | `Vec3` | Position |
|
|
1515
|
-
| `tangent` | `Vec3` | Tangent direction (will be normalized internally) |
|
|
1516
|
-
| `curvature?` | `Vec3` | Second derivative / curvature vector. Default [0, 0, 0]. |
|
|
1517
|
-
| `weight?` | `number` | Weight: scales tangent magnitude relative to chord length. Default 1.0. |
|
|
1518
|
-
|
|
1519
1583
|
#### `loft()` — Loft between multiple sketches along Z stations.
|
|
1520
1584
|
|
|
1521
1585
|
Profiles can differ in topology and vertex count: interpolation is done on signed-distance fields and meshed with level-set extraction. Heights must be strictly increasing. Compatible loft stacks can also stay on the maintained export-backend path.
|
|
@@ -1526,41 +1590,6 @@ Performance note: loft is significantly heavier than primitive/extrude/revolve.
|
|
|
1526
1590
|
loft(profiles: Sketch[], heights: number[], options?: LoftOptions): Shape
|
|
1527
1591
|
```
|
|
1528
1592
|
|
|
1529
|
-
#### `loftAlongSpine()` — Loft between multiple profiles positioned along an arbitrary 3D spine curve.
|
|
1530
|
-
|
|
1531
|
-
Unlike loft() which only supports Z heights, loftAlongSpine() places each profile at a position along a 3D spine, oriented perpendicular to the spine tangent. This enables lofting along curved paths — e.g., a wing root-to-tip transition that follows a swept-back leading edge.
|
|
1532
|
-
|
|
1533
|
-
The tValues array specifies where each profile sits along the spine (0 = start, 1 = end). Must have the same length as profiles and be in [0, 1].
|
|
1534
|
-
|
|
1535
|
-
Internally uses variableSweep infrastructure with SDF interpolation.
|
|
1536
|
-
|
|
1537
|
-
Performance note: uses level-set meshing, heavier than simple loft().
|
|
1538
|
-
|
|
1539
|
-
```ts
|
|
1540
|
-
loftAlongSpine(profiles: Sketch[], spine: Curve3D | Vec3[], tValues: number[], options?: LoftAlongSpineOptions): Shape
|
|
1541
|
-
```
|
|
1542
|
-
|
|
1543
|
-
**`LoftAlongSpineOptions`**
|
|
1544
|
-
|
|
1545
|
-
| Option | Type | Description |
|
|
1546
|
-
|--------|------|-------------|
|
|
1547
|
-
| `samples?` | `number` | Number of samples when spine is a Curve3D. Default 48. |
|
|
1548
|
-
| `edgeLength?` | `number` | Marching-grid edge length for level-set meshing. Smaller = finer. |
|
|
1549
|
-
| `boundsPadding?` | `number` | Optional extra bounds padding. |
|
|
1550
|
-
| `up?` | `Vec3` | Preferred "up" vector for local profile frame. Auto fallback is used near parallel segments. |
|
|
1551
|
-
|
|
1552
|
-
#### `spline3d()` — Create a reusable 3D spline curve object (Catmull-Rom).
|
|
1553
|
-
|
|
1554
|
-
The returned Curve3D provides sample(), pointAt(t), tangentAt(t), and length() for downstream use in sweep() or manual path operations.
|
|
1555
|
-
|
|
1556
|
-
```ts
|
|
1557
|
-
spline3d(points: Vec3[], options?: Spline3DOptions): Curve3D
|
|
1558
|
-
```
|
|
1559
|
-
|
|
1560
|
-
**`Spline3DOptions`**
|
|
1561
|
-
- `closed?: boolean` — Closed loop (default false).
|
|
1562
|
-
- `tension?: number` — Catmull-Rom tension in [0, 1]. 0 = very round, 1 = linear-ish. Default 0.5.
|
|
1563
|
-
|
|
1564
1593
|
#### `surfacePatch()` — Create a smooth surface patch from 4 boundary curves (Coons patch).
|
|
1565
1594
|
|
|
1566
1595
|
The four curves form the boundary of a quadrilateral patch:
|
|
@@ -1620,54 +1649,6 @@ variableSweep(spine: SweepPathInput, sections: VariableSweepSection[], options?:
|
|
|
1620
1649
|
| `boundsPadding?` | `number` | Optional extra bounds padding. |
|
|
1621
1650
|
| `up?` | `Vec3` | Preferred "up" vector for local profile frame. Auto fallback is used near parallel segments. |
|
|
1622
1651
|
|
|
1623
|
-
#### `transitionCurve()` — Create a smooth transition curve between two edges.
|
|
1624
|
-
|
|
1625
|
-
Returns a `HermiteCurve3D` that starts at `edgeA.point` tangent to `edgeA.tangent` and ends at `edgeB.point` tangent to `edgeB.tangent`.
|
|
1626
|
-
|
|
1627
|
-
The curve maintains G1 continuity (matching tangent direction) at both endpoints. Weight parameters control the shape of the transition.
|
|
1628
|
-
|
|
1629
|
-
```js
|
|
1630
|
-
// Connect two edges with a balanced transition
|
|
1631
|
-
const curve = transitionCurve(
|
|
1632
|
-
{ point: [0, 0, 0], tangent: [1, 0, 0] },
|
|
1633
|
-
{ point: [10, 5, 0], tangent: [1, 0, 0] },
|
|
1634
|
-
);
|
|
1635
|
-
```
|
|
1636
|
-
|
|
1637
|
-
// Weighted: curve hugs edge A longer const weighted = transitionCurve( { point: [0, 0, 0], tangent: [1, 0, 0] }, { point: [10, 5, 0], tangent: [1, 0, 0] }, { weightA: 2.0, weightB: 0.5 }, );
|
|
1638
|
-
|
|
1639
|
-
```
|
|
1640
|
-
|
|
1641
|
-
```ts
|
|
1642
|
-
transitionCurve(edgeA: TransitionEdge, edgeB: TransitionEdge, options?: TransitionCurveOptions): HermiteCurve3D
|
|
1643
|
-
```
|
|
1644
|
-
|
|
1645
|
-
**`TransitionEdge`**
|
|
1646
|
-
- `point: Vec3` — Connection point on the edge. Can be any point along the edge where the transition should connect.
|
|
1647
|
-
- `tangent: Vec3` — Tangent direction at the connection point. This is the direction the curve should initially follow when leaving this edge. For a straight edge, this is typically the edge direction pointing "outward" (away from the body of the edge, toward the other edge).
|
|
1648
|
-
- `normal?: Vec3` — Surface normal at the connection point (optional). Used as a hint for the sweep frame's up vector.
|
|
1649
|
-
|
|
1650
|
-
#### `transitionSurface()` — Create a solid transition surface between two edges by sweeping a profile along a Hermite transition curve.
|
|
1651
|
-
|
|
1652
|
-
This produces a watertight solid that smoothly connects the two edges. Works with both Manifold and OCCT backends.
|
|
1653
|
-
|
|
1654
|
-
```js
|
|
1655
|
-
// Circular tube connecting two edges
|
|
1656
|
-
const tube = transitionSurface(
|
|
1657
|
-
{ point: [0, 0, 0], tangent: [1, 0, 0] },
|
|
1658
|
-
{ point: [10, 5, 3], tangent: [0, 1, 0] },
|
|
1659
|
-
{ radius: 0.5 },
|
|
1660
|
-
);
|
|
1661
|
-
```
|
|
1662
|
-
|
|
1663
|
-
// Custom profile with weights const custom = transitionSurface( { point: [0, 0, 0], tangent: [1, 0, 0] }, { point: [10, 5, 3], tangent: [0, 1, 0] }, { profile: mySketch, weightA: 1.5, weightB: 0.8 }, );
|
|
1664
|
-
|
|
1665
|
-
```
|
|
1666
|
-
|
|
1667
|
-
```ts
|
|
1668
|
-
transitionSurface(edgeA: TransitionEdge, edgeB: TransitionEdge, options?: TransitionSurfaceOptions): Shape
|
|
1669
|
-
```
|
|
1670
|
-
|
|
1671
1652
|
---
|
|
1672
1653
|
|
|
1673
1654
|
## C5: Topology Query
|
|
@@ -1732,9 +1713,9 @@ selectEdge(shape: Shape, query?: EdgeQuery): EdgeSegment
|
|
|
1732
1713
|
| `minLength?` | `number` | Filter: minimum edge length. |
|
|
1733
1714
|
| `maxLength?` | `number` | Filter: maximum edge length. |
|
|
1734
1715
|
| `within?` | `BoundingRegion` | Filter: edge midpoint must be within this bounding region. |
|
|
1735
|
-
| `atZ?` | `number` | Shorthand: edge midpoint Z
|
|
1736
|
-
| `tolerance?` | `number` | Position tolerance for approximate matches
|
|
1737
|
-
| `angleTolerance?` | `number` | Angular tolerance in degrees for `parallel`/`perpendicular` filters
|
|
1716
|
+
| `atZ?` | `number` | Shorthand: edge midpoint Z is approximately this value within `tolerance`. |
|
|
1717
|
+
| `tolerance?` | `number` | Position tolerance for approximate matches. Used by `atZ` and `near`. Default: `1.0`. |
|
|
1718
|
+
| `angleTolerance?` | `number` | Angular tolerance in degrees for `parallel`/`perpendicular` filters. Default: `10`. |
|
|
1738
1719
|
|
|
1739
1720
|
`BoundingRegion`: `{ xMin?: number, xMax?: number, yMin?: number, yMax?: number, zMin?: number, zMax?: number }`
|
|
1740
1721
|
|
|
@@ -2332,31 +2313,43 @@ Points.polar(length: number, angleDeg: number, from?: [ number, number ]): [ num
|
|
|
2332
2313
|
|
|
2333
2314
|
Compose parts with joints for kinematic simulation.
|
|
2334
2315
|
|
|
2335
|
-
#### `assembly()` — Create an assembly container with named parts and
|
|
2316
|
+
#### `assembly()` — Create an assembly container with named parts, connectors, and kinematic links.
|
|
2336
2317
|
|
|
2337
|
-
**Use this from iteration 1 for any model with moving parts.**
|
|
2318
|
+
**Use this from iteration 1 for any model with moving parts.** Do not build one static pose and retrofit motion later.
|
|
2338
2319
|
|
|
2339
|
-
|
|
2320
|
+
Links are named kinematic markers in the assembly. `edgeBetweenLinks()` records structural distances or visual relationships. `addAngleBetweenLinks()` records measured, limited, or controlled angles. These APIs solve point positions, not rigid-body frames.
|
|
2340
2321
|
|
|
2341
|
-
|
|
2322
|
+
`addPart(..., { mate })` attaches a part connector origin to a solved link point by translation only. It is right for markers and point-following geometry. Use `connect()` / `match()` for physical articulated parts that need full connector frame alignment and deterministic rest orientation.
|
|
2342
2323
|
|
|
2343
|
-
|
|
2324
|
+
Return an `Assembly` directly to expose its connector joints and driven link controls in the editor. Moving those controls re-runs the assembly solve with the new state, so closed-loop link/edge mechanisms move through the real kinematic solver instead of a viewport-only forward-kinematics approximation.
|
|
2325
|
+
|
|
2326
|
+
If no link in a connected kinematic component is fixed, ForgeCAD chooses a deterministic gauge link for solving and reports a floating-component warning.
|
|
2327
|
+
|
|
2328
|
+
The legacy joint-chain APIs still exist for compatibility and exporter plumbing. New work should choose between point-link kinematics and connector-frame joints based on whether the part needs orientation.
|
|
2344
2329
|
|
|
2345
2330
|
For multi-file assemblies, a file that returns an `Assembly` is importable via `require()` and yields an `ImportedAssembly`. Use `mergeInto()` to flatten a sub-assembly into a parent assembly.
|
|
2346
2331
|
|
|
2332
|
+
**Point-link example**
|
|
2333
|
+
|
|
2334
|
+
This snippet mates a marker to the solved `tip` point. It does not orient a bar along `ground -> tip`.
|
|
2335
|
+
|
|
2347
2336
|
```ts
|
|
2348
|
-
const
|
|
2349
|
-
|
|
2350
|
-
|
|
2337
|
+
const marker = box(8, 8, 4).withConnectors({
|
|
2338
|
+
center: connector({ origin: [0, 0, 0], axis: [0, 0, 1] }),
|
|
2339
|
+
});
|
|
2340
|
+
|
|
2341
|
+
const mech = assembly("Linkage")
|
|
2342
|
+
.link("ground", { at: [0, 0, 0], fixed: true })
|
|
2343
|
+
.link("worldX", { at: [10, 0, 0], fixed: true })
|
|
2344
|
+
.link("tip", { at: [40, 0, 0] })
|
|
2345
|
+
.edgeBetweenLinks("ground", "tip", { name: "bar" })
|
|
2346
|
+
.addAngleBetweenLinks("worldX", "ground", "tip", {
|
|
2347
|
+
name: "theta",
|
|
2348
|
+
control: { min: 0, max: 120, default: 30 },
|
|
2351
2349
|
})
|
|
2352
|
-
.addPart("
|
|
2353
|
-
.addRevolute("shoulder", "base", "link", {
|
|
2354
|
-
axis: [0, 1, 0],
|
|
2355
|
-
min: -30, max: 120, default: 25,
|
|
2356
|
-
frame: Transform.identity().translate(0, 0, 20),
|
|
2357
|
-
});
|
|
2350
|
+
.addPart("Tip marker", marker, { mate: { connector: "center", toLink: "tip" } });
|
|
2358
2351
|
|
|
2359
|
-
return mech;
|
|
2352
|
+
return mech;
|
|
2360
2353
|
```
|
|
2361
2354
|
|
|
2362
2355
|
```ts
|
|
@@ -2380,28 +2373,15 @@ bomToCsv(rows: BomRow[]): string
|
|
|
2380
2373
|
| `tags?` | `string \| readonly string[]` | Viewport organization tags applied to scene objects produced from this part. |
|
|
2381
2374
|
| `material?`, `process?`, `tolerance?`, `qty?`, `notes?`, `densityKgM3?`, `massKg?` | | — |
|
|
2382
2375
|
|
|
2383
|
-
|
|
2376
|
+
<!-- forgecad-skill:exclude-start symbol="jointsView" reason="Compatibility-only viewport FK API. Prefer returning `Assembly` directly so controls move through the solver-backed link/edge kinematics model." -->
|
|
2377
|
+
#### `jointsView()` — Register legacy viewport-only mechanism controls that animate returned objects without re-running the script.
|
|
2384
2378
|
|
|
2385
|
-
This
|
|
2386
|
-
|
|
2387
|
-
```ts
|
|
2388
|
-
const arm = joint("Shoulder", armShape, [0, 0, 20], {
|
|
2389
|
-
axis: [0, 1, 0],
|
|
2390
|
-
min: -30, max: 120, default: 25,
|
|
2391
|
-
});
|
|
2392
|
-
return arm;
|
|
2393
|
-
```
|
|
2394
|
-
|
|
2395
|
-
```ts
|
|
2396
|
-
joint(name: string, shape: Shape, pivot: [ number, number, number ], opts?: RevoluteJointOpts): Shape
|
|
2397
|
-
```
|
|
2398
|
-
|
|
2399
|
-
`RevoluteJointOpts`: `{ axis?: [ number, number, number ], min?: number, max?: number, default?: number, unit?: string, reverse?: boolean }`
|
|
2400
|
-
|
|
2401
|
-
#### `jointsView()` — Register viewport-only mechanism controls that animate returned objects without re-running the script.
|
|
2379
|
+
> **Not included in ForgeCAD AI skill context yet.** This API remains visible in human docs, but is intentionally omitted from shipped agent skills until it is ready for agent-first use. Compatibility-only viewport FK API. Prefer returning `Assembly` directly so controls move through the solver-backed link/edge kinematics model.
|
|
2402
2380
|
|
|
2403
2381
|
Defines joints (revolute or prismatic), optional gear/rack couplings, and named animations. The viewport resolves transforms through the joint chain at display time — the script geometry is computed only once at rest pose.
|
|
2404
2382
|
|
|
2383
|
+
For `Assembly` mechanisms, prefer returning the `Assembly` directly. Returned assemblies expose solver-backed controls automatically, so link/edge closed loops move through the real assembly solver instead of this viewport-only FK layer.
|
|
2384
|
+
|
|
2405
2385
|
**Critical:** Solve the assembly at **rest pose** (all animated joints = 0). The viewport applies `jointsView` transforms on top of the returned scene. If geometry is already solved at non-zero angles, animation will double-rotate everything.
|
|
2406
2386
|
|
|
2407
2387
|
```js
|
|
@@ -2433,6 +2413,8 @@ return solved;
|
|
|
2433
2413
|
|
|
2434
2414
|
Animation values are interpolated linearly between keyframes. ForgeCAD does **not** auto-wrap revolute values across `-180/180`. Keep keyframe values continuous — a `-180 -> 171` jump spins the part the long way around. Use `-180 -> -189` instead. Author high-speed multi-turn joints as accumulating angles (`0, 360, 720, ...`) with `continuous: true`.
|
|
2435
2415
|
|
|
2416
|
+
**Mirrored revolute axes:** `default` values and animation keyframes are physical joint values, signed by the joint axis. In a bilateral mechanism, mirrored hinge axes such as `[1, 0, 0]` and `[-1, 0, 0]` need opposite physical values for the same mirrored pose. Negate the mirrored revolute track and mirror physical limits as `[min, max] -> [-max, -min]`. Prismatic tracks do not have this handedness flip.
|
|
2417
|
+
|
|
2436
2418
|
**Tick-based keyframes:** Omit `at` from all keyframes to auto-distribute by tick weight:
|
|
2437
2419
|
|
|
2438
2420
|
```js
|
|
@@ -2482,6 +2464,7 @@ jointsView(options?: JointsViewOptions): void
|
|
|
2482
2464
|
- `at?: number` — Timeline position [0, 1]. If omitted from ALL keyframes, positions are auto-computed from tick weights.
|
|
2483
2465
|
- `ticks?: number` — Relative weight of the segment from this keyframe to the next (default 1). Only used in tick-based mode (when `at` is omitted). Last keyframe's ticks value is ignored.
|
|
2484
2466
|
- Also: `values: Record<string, number>`
|
|
2467
|
+
<!-- forgecad-skill:exclude-end -->
|
|
2485
2468
|
|
|
2486
2469
|
---
|
|
2487
2470
|
|
|
@@ -2736,7 +2719,7 @@ Call `robotExport()` alongside your assembly definition. The CLI commands `forge
|
|
|
2736
2719
|
|
|
2737
2720
|
- Mesh-based inertia tensors (full 6-component, not bounding-box approximations)
|
|
2738
2721
|
- Separate collision meshes (convex hull by default — ~50–80% smaller)
|
|
2739
|
-
- Joint
|
|
2722
|
+
- Joint limits, effort/velocity/damping/friction metadata from assembly joints
|
|
2740
2723
|
|
|
2741
2724
|
**Collision mesh modes** (set per-link via `links["PartName"].collision`):
|
|
2742
2725
|
|
|
@@ -2752,7 +2735,7 @@ Call `robotExport()` alongside your assembly definition. The CLI commands `forge
|
|
|
2752
2735
|
- Revolute `velocity` is in degrees/second in Forge; exporters convert to rad/s.
|
|
2753
2736
|
- Prismatic distances are in mm in Forge; exported in meters.
|
|
2754
2737
|
- `massKg` is preferred; `densityKgM3` is used when mass is unknown.
|
|
2755
|
-
-
|
|
2738
|
+
- Compatibility coupling metadata, when present, maps only the primary term (largest ratio) to `<mimic>` — SDF/URDF support single-leader mimic only. Dropped terms emit a warning.
|
|
2756
2739
|
|
|
2757
2740
|
```ts
|
|
2758
2741
|
const rover = assembly("Scout")
|
|
@@ -2808,9 +2791,9 @@ robotExport(options: RobotExportOptions): CollectedRobotExport
|
|
|
2808
2791
|
|
|
2809
2792
|
**`CollectedRobotExport`**: `modelName: string`, `assembly: AssemblyDefinition`, `state: JointState`, `static: boolean`, `selfCollide: boolean`, `allowAutoDisable: boolean`, `links: Record<string, RobotLinkExportOptions>`, `joints: Record<string, RobotJointExportOptions>`, `plugins: { diffDrive?: RobotDiffDrivePluginOptions; jointStatePublisher?: RobotJointStatePublisherOptions; }`, `world: RobotWorldOptions | null`
|
|
2810
2793
|
|
|
2811
|
-
|
|
2794
|
+
**`AssemblyDefinition`**: `name: string`, `parts: AssemblyPartDef[]`, `joints: AssemblyJointDef[]`, `jointCouplings: AssemblyJointCouplingDef[]`, `kinematics: AssemblyKinematicGraphDef`
|
|
2812
2795
|
|
|
2813
|
-
`AssemblyPartDef`: `{ name: string, part: AssemblyPart, base: Transform, metadata?: PartMetadata }`
|
|
2796
|
+
`AssemblyPartDef`: `{ name: string, part: AssemblyPart, base: Transform, metadata?: PartMetadata, mates: AssemblyPartMateInput[] }`
|
|
2814
2797
|
|
|
2815
2798
|
**`PartMetadata`**
|
|
2816
2799
|
|
|
@@ -2819,6 +2802,11 @@ robotExport(options: RobotExportOptions): CollectedRobotExport
|
|
|
2819
2802
|
| `tags?` | `string \| readonly string[]` | Viewport organization tags applied to scene objects produced from this part. |
|
|
2820
2803
|
| `material?`, `process?`, `tolerance?`, `qty?`, `notes?`, `densityKgM3?`, `massKg?` | | — |
|
|
2821
2804
|
|
|
2805
|
+
**`AssemblyPartMateInput`**
|
|
2806
|
+
- `connector: string` — Name of a connector declared on the part (via `withConnectors()`).
|
|
2807
|
+
- `toLink: string` — Name of the link this connector's origin is pinned to.
|
|
2808
|
+
- `aimLink?: string` — Optional second link to orient toward. When set, the part is rotated so the connector's **axis** aims from `toLink` toward `aimLink`, posing an oriented bone instead of only translating it. For full pose without relying on a connector axis, declare a second mate (two connectors → two links).
|
|
2809
|
+
|
|
2822
2810
|
**`AssemblyJointDef`**: `name: string`, `type: JointType`, `parent: string`, `child: string`, `frame: Transform`, `axis: Vec3`, `min?: number`, `max?: number`, `defaultValue: number`, `unit?: string`, `effort?: number`, `velocity?: number`, `damping?: number`, `friction?: number`, `connectorRefs?: JointConnectorRefs`
|
|
2823
2811
|
|
|
2824
2812
|
`JointConnectorRefs`: `{ parent: string, child: string, parentAlign?: PortAlign, childAlign?: PortAlign }`
|
|
@@ -2827,6 +2815,16 @@ robotExport(options: RobotExportOptions): CollectedRobotExport
|
|
|
2827
2815
|
|
|
2828
2816
|
`JointCouplingTermRecord`: `{ joint: string, ratio: number }`
|
|
2829
2817
|
|
|
2818
|
+
`AssemblyKinematicGraphDef`: `{ links: AssemblyLinkDef[], edges: AssemblyEdgeBetweenLinksDef[], angles: AssemblyAngleBetweenLinksDef[] }`
|
|
2819
|
+
|
|
2820
|
+
`AssemblyLinkDef`: `{ name: string, at: Vec3, fixed: boolean, metadata?: Record<string, unknown> }`
|
|
2821
|
+
|
|
2822
|
+
**`AssemblyEdgeBetweenLinksDef`**: `name: string`, `a: string`, `b: string`, `length: number | null`, `min?: number`, `max?: number`, `visualOnly: boolean`, `control?: AssemblyKinematicControlOptions`, `metadata?: Record<string, unknown>`
|
|
2823
|
+
|
|
2824
|
+
`AssemblyKinematicControlOptions`: `{ min?: number, max?: number, default?: number, unit?: string }`
|
|
2825
|
+
|
|
2826
|
+
**`AssemblyAngleBetweenLinksDef`**: `name: string`, `a: string`, `b: string`, `c: string`, `target?: number`, `min?: number`, `max?: number`, `control?: AssemblyKinematicControlOptions`, `metadata?: Record<string, unknown>`
|
|
2827
|
+
|
|
2830
2828
|
#### `sheetMetal()` — Create a parametric sheet metal part with flanges, bend allowances, and flat-pattern unfolding.
|
|
2831
2829
|
|
|
2832
2830
|
`sheetMetal()` keeps one semantic model and derives both a folded 3D solid and an accurate flat pattern from it. The K-factor bend allowance is applied during unfolding. This is a strict v1 subset — it does not infer sheet metal from arbitrary solids.
|
|
@@ -3424,7 +3422,7 @@ showLabels(shape: Shape): Shape
|
|
|
3424
3422
|
|
|
3425
3423
|
#### `viewConfig()` — Configure viewport helper visuals for the current script execution.
|
|
3426
3424
|
|
|
3427
|
-
Controls renderer-only overlays that appear in the viewport but are not part of the geometry. Currently supports the joint overlay that renders axis arrows and arc indicators when
|
|
3425
|
+
Controls renderer-only overlays that appear in the viewport but are not part of the geometry. Currently supports the joint overlay that renders axis arrows and arc indicators when joint controls are active. Multiple calls merge — later values override earlier ones per key.
|
|
3428
3426
|
|
|
3429
3427
|
This does **not** trigger a geometry recompute; it only affects the visual helpers drawn on top of the 3D scene.
|
|
3430
3428
|
|