Circle function and UI tool (#3860)
* circle * fix another example * fix bad comment * toPoint fix * cargo fmt * resolve most of the tests * fix last test * missed circle in bracket * remove console error * fmt * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * trigger ci * remove three dot menu for circle * make sure circle can be extruded * fix up after merge * add extrude test for circle * clean up * typo * A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest) * Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)" This reverts commit03f8eeb542
. * update docs again * cmd bar test serialisation improvements * tiny clean up * fix after: Replace kittycad crate with kittycad-modeling-cmds * fmt * rename fix * Update src/lib/toolbar.ts Co-authored-by: Frank Noirot <frank@zoo.dev> * add another error to list * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest) * image updates * Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)" This reverts commit505bb20bea
. * update markdown * skip un reproducable windows test failure * rust review * leave issue todo comment --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Frank Noirot <frank@zoo.dev>
2
.github/workflows/playwright.yml
vendored
@ -263,7 +263,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-14]
|
os: [ubuntu-latest, windows-latest, macos-14]
|
||||||
timeout-minutes: 40
|
timeout-minutes: 60
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
needs: check-rust-changes
|
needs: check-rust-changes
|
||||||
steps:
|
steps:
|
||||||
|
@ -270,6 +270,26 @@ const extrusion = extrude(5, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -479,6 +499,26 @@ const extrusion = extrude(5, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -274,6 +274,26 @@ const extrusion = extrude(5, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -483,6 +503,26 @@ const extrusion = extrude(5, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -189,6 +189,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -398,6 +418,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -609,6 +649,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -818,6 +878,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -188,6 +188,26 @@ const extrusion = extrude(10, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -397,6 +417,26 @@ const extrusion = extrude(10, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -608,6 +648,26 @@ const extrusion = extrude(10, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -817,6 +877,26 @@ const extrusion = extrude(10, sketch001)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -190,6 +190,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -399,6 +419,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -610,6 +650,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -819,6 +879,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -282,6 +282,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -491,6 +511,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -702,6 +742,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -911,6 +971,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -187,6 +187,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -396,6 +416,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -607,6 +647,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -816,6 +876,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -187,6 +187,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -396,6 +416,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -607,6 +647,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -816,6 +876,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -200,6 +200,26 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -409,6 +429,26 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -620,6 +660,26 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -829,6 +889,26 @@ const exampleSketch = startSketchOn('XZ')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -182,6 +182,26 @@ decagon(5.0)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -391,6 +411,26 @@ decagon(5.0)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -594,6 +634,26 @@ decagon(5.0)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -803,6 +863,26 @@ decagon(5.0)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -193,6 +193,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -402,6 +422,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -613,6 +653,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -822,6 +882,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -448,6 +448,26 @@ const sketch001 = startSketchOn(part001, chamfer1)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -852,6 +872,26 @@ const sketch001 = startSketchOn(part001, chamfer1)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -9,14 +9,14 @@ Construct a 2-dimensional circle, of the specified radius, centered at
|
|||||||
the provided (x, y) origin point.
|
the provided (x, y) origin point.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
circle(center: [number], radius: number, sketch_surface_or_group: SketchSurfaceOrGroup, tag?: TagDeclarator) -> SketchGroup
|
circle(data: CircleData, sketch_surface_or_group: SketchSurfaceOrGroup, tag?: TagDeclarator) -> SketchGroup
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const exampleSketch = startSketchOn("-XZ")
|
const exampleSketch = startSketchOn("-XZ")
|
||||||
|> circle([0, 0], 10, %)
|
|> circle({ center: [0, 0], radius: 10 }, %)
|
||||||
|
|
||||||
const example = extrude(5, exampleSketch)
|
const example = extrude(5, exampleSketch)
|
||||||
```
|
```
|
||||||
@ -30,7 +30,7 @@ const exampleSketch = startSketchOn("XZ")
|
|||||||
|> line([0, 30], %)
|
|> line([0, 30], %)
|
||||||
|> line([-30, 0], %)
|
|> line([-30, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([0, 15], 5, %), %)
|
|> hole(circle({ center: [0, 15], radius: 5 }, %), %)
|
||||||
|
|
||||||
const example = extrude(5, exampleSketch)
|
const example = extrude(5, exampleSketch)
|
||||||
```
|
```
|
||||||
@ -39,8 +39,15 @@ const example = extrude(5, exampleSketch)
|
|||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
* `center`: `[number]` (REQUIRED)
|
* `data`: `CircleData` - Data for drawing an circle (REQUIRED)
|
||||||
* `radius`: `number` (REQUIRED)
|
```js
|
||||||
|
{
|
||||||
|
// The center of the circle.
|
||||||
|
center: [number, number],
|
||||||
|
// The circle radius
|
||||||
|
radius: number,
|
||||||
|
}
|
||||||
|
```
|
||||||
* `sketch_surface_or_group`: `SketchSurfaceOrGroup` - A sketch surface or a sketch group. (REQUIRED)
|
* `sketch_surface_or_group`: `SketchSurfaceOrGroup` - A sketch surface or a sketch group. (REQUIRED)
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
@ -186,6 +193,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -562,6 +589,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -773,6 +820,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -982,6 +1049,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -188,6 +188,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -397,6 +417,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -608,6 +648,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -817,6 +877,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -213,6 +213,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -423,6 +443,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -753,6 +793,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -445,6 +445,26 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -849,6 +869,26 @@ const mountingPlate = extrude(thickness, mountingPlateSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -16,7 +16,7 @@ helix(data: HelixData, extrude_group: ExtrudeGroup) -> ExtrudeGroup
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
const part001 = startSketchOn('XY')
|
const part001 = startSketchOn('XY')
|
||||||
|> circle([5, 5], 10, %)
|
|> circle({ center: [5, 5], radius: 10 }, %)
|
||||||
|> extrude(10, %)
|
|> extrude(10, %)
|
||||||
|> helix({
|
|> helix({
|
||||||
angleStart: 0,
|
angleStart: 0,
|
||||||
@ -316,6 +316,26 @@ const part001 = startSketchOn('XY')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -711,6 +731,26 @@ const part001 = startSketchOn('XY')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
126
docs/kcl/hole.md
@ -21,8 +21,8 @@ const exampleSketch = startSketchOn('XY')
|
|||||||
|> line([5, 0], %)
|
|> line([5, 0], %)
|
||||||
|> line([0, -5], %)
|
|> line([0, -5], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([1, 1], .25, %), %)
|
|> hole(circle({ center: [1, 1], radius: .25 }, %), %)
|
||||||
|> hole(circle([1, 4], .25, %), %)
|
|> hole(circle({ center: [1, 4], radius: .25 }, %), %)
|
||||||
|
|
||||||
const example = extrude(1, exampleSketch)
|
const example = extrude(1, exampleSketch)
|
||||||
```
|
```
|
||||||
@ -41,7 +41,7 @@ fn squareHoleSketch = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const exampleSketch = startSketchOn('-XZ')
|
const exampleSketch = startSketchOn('-XZ')
|
||||||
|> circle([0, 0], 3, %)
|
|> circle({ center: [0, 0], radius: 3 }, %)
|
||||||
|> hole(squareHoleSketch(), %)
|
|> hole(squareHoleSketch(), %)
|
||||||
const example = extrude(1, exampleSketch)
|
const example = extrude(1, exampleSketch)
|
||||||
```
|
```
|
||||||
@ -199,6 +199,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -409,6 +429,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -611,6 +651,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -820,6 +880,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -1022,6 +1102,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -1231,6 +1331,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -54,11 +54,17 @@ const case = startSketchOn('-XZ')
|
|||||||
|> extrude(65, %)
|
|> extrude(65, %)
|
||||||
|
|
||||||
const thing1 = startSketchOn(case, 'end')
|
const thing1 = startSketchOn(case, 'end')
|
||||||
|> circle([-size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [-size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
const thing2 = startSketchOn(case, 'end')
|
const thing2 = startSketchOn(case, 'end')
|
||||||
|> circle([size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
hollow(0.5, case)
|
hollow(0.5, case)
|
||||||
@ -343,6 +349,26 @@ hollow(0.5, case)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -738,6 +764,26 @@ hollow(0.5, case)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -21,7 +21,7 @@ int(num: number) -> i64
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
const sketch001 = startSketchOn('XZ')
|
const sketch001 = startSketchOn('XZ')
|
||||||
|> circle([0, 0], 2, %)
|
|> circle({ center: [0, 0], radius: 2 }, %)
|
||||||
const extrude001 = extrude(5, sketch001)
|
const extrude001 = extrude(5, sketch001)
|
||||||
|
|
||||||
const pattern01 = patternTransform(int(ceil(5 / 2)), (id) => {
|
const pattern01 = patternTransform(int(ceil(5 / 2)), (id) => {
|
||||||
|
@ -179,6 +179,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -388,6 +408,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -179,6 +179,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -388,6 +408,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -192,6 +192,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -401,6 +421,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -612,6 +652,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -821,6 +881,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -179,6 +179,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -388,6 +408,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -599,6 +639,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -808,6 +868,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -197,6 +197,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -407,6 +427,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -16,7 +16,7 @@ patternCircular3d(data: CircularPattern3dData, extrude_group_set: ExtrudeGroupSe
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
const exampleSketch = startSketchOn('XZ')
|
const exampleSketch = startSketchOn('XZ')
|
||||||
|> circle([0, 0], 1, %)
|
|> circle({ center: [0, 0], radius: 1 }, %)
|
||||||
|
|
||||||
const example = extrude(-5, exampleSketch)
|
const example = extrude(-5, exampleSketch)
|
||||||
|> patternCircular3d({
|
|> patternCircular3d({
|
||||||
@ -321,6 +321,26 @@ const example = extrude(-5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -16,7 +16,7 @@ patternLinear2d(data: LinearPattern2dData, sketch_group_set: SketchGroupSet) ->
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
const exampleSketch = startSketchOn('XZ')
|
const exampleSketch = startSketchOn('XZ')
|
||||||
|> circle([0, 0], 1, %)
|
|> circle({ center: [0, 0], radius: 1 }, %)
|
||||||
|> patternLinear2d({
|
|> patternLinear2d({
|
||||||
axis: [1, 0],
|
axis: [1, 0],
|
||||||
repetitions: 6,
|
repetitions: 6,
|
||||||
@ -190,6 +190,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -400,6 +420,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -319,6 +319,26 @@ const example = extrude(1, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -32,7 +32,7 @@ fn transform = (replicaId) => {
|
|||||||
fn layer = () => {
|
fn layer = () => {
|
||||||
return startSketchOn("XY")
|
return startSketchOn("XY")
|
||||||
// or some other plane idk
|
// or some other plane idk
|
||||||
|> circle([0, 0], 1, %, $tag1)
|
|> circle({ center: [0, 0], radius: 1 }, %, $tag1)
|
||||||
|> extrude(h, %)
|
|> extrude(h, %)
|
||||||
}
|
}
|
||||||
// The vase is 100 layers tall.
|
// The vase is 100 layers tall.
|
||||||
@ -321,6 +321,26 @@ let vase = layer()
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -22,7 +22,10 @@ pi() -> number
|
|||||||
const circumference = 70
|
const circumference = 70
|
||||||
|
|
||||||
const exampleSketch = startSketchOn("XZ")
|
const exampleSketch = startSketchOn("XZ")
|
||||||
|> circle([0, 0], circumference / (2 * pi()), %)
|
|> circle({
|
||||||
|
center: [0, 0],
|
||||||
|
radius: circumference / (2 * pi())
|
||||||
|
}, %)
|
||||||
|
|
||||||
const example = extrude(5, exampleSketch)
|
const example = extrude(5, exampleSketch)
|
||||||
```
|
```
|
||||||
|
@ -180,6 +180,26 @@ const sketch001 = startSketchOn('XY')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -389,6 +409,26 @@ const sketch001 = startSketchOn('XY')
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -93,11 +93,17 @@ const case = startSketchOn('-XZ')
|
|||||||
|> extrude(65, %)
|
|> extrude(65, %)
|
||||||
|
|
||||||
const thing1 = startSketchOn(case, 'end')
|
const thing1 = startSketchOn(case, 'end')
|
||||||
|> circle([-size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [-size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
const thing2 = startSketchOn(case, 'end')
|
const thing2 = startSketchOn(case, 'end')
|
||||||
|> circle([size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
// We put "case" in the shell function to shell the entire object.
|
// We put "case" in the shell function to shell the entire object.
|
||||||
@ -118,11 +124,17 @@ const case = startSketchOn('XY')
|
|||||||
|> extrude(65, %)
|
|> extrude(65, %)
|
||||||
|
|
||||||
const thing1 = startSketchOn(case, 'end')
|
const thing1 = startSketchOn(case, 'end')
|
||||||
|> circle([-size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [-size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
const thing2 = startSketchOn(case, 'end')
|
const thing2 = startSketchOn(case, 'end')
|
||||||
|> circle([size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
// We put "thing1" in the shell function to shell the end face of the object.
|
// We put "thing1" in the shell function to shell the end face of the object.
|
||||||
@ -146,11 +158,17 @@ const case = startSketchOn('XY')
|
|||||||
|> extrude(65, %)
|
|> extrude(65, %)
|
||||||
|
|
||||||
const thing1 = startSketchOn(case, 'end')
|
const thing1 = startSketchOn(case, 'end')
|
||||||
|> circle([-size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [-size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
const thing2 = startSketchOn(case, 'end')
|
const thing2 = startSketchOn(case, 'end')
|
||||||
|> circle([size / 2, -size / 2], 25, %)
|
|> circle({
|
||||||
|
center: [size / 2, -size / 2],
|
||||||
|
radius: 25
|
||||||
|
}, %)
|
||||||
|> extrude(50, %)
|
|> extrude(50, %)
|
||||||
|
|
||||||
// We put "thing1" and "thing2" in the shell function to shell the end face of the object.
|
// We put "thing1" and "thing2" in the shell function to shell the end face of the object.
|
||||||
@ -533,6 +551,26 @@ shell({ faces: ['end'], thickness: 5 }, [thing1, thing2])
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -932,6 +970,26 @@ shell({ faces: ['end'], thickness: 5 }, [thing1, thing2])
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -258,6 +258,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -561,6 +581,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -770,6 +810,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -205,6 +205,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -414,6 +434,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -327,6 +327,26 @@ const a1 = startSketchOn({
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -743,6 +763,26 @@ const a1 = startSketchOn({
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
18025
docs/kcl/std.json
@ -188,6 +188,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -397,6 +417,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -608,6 +648,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -817,6 +877,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -179,6 +179,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -388,6 +408,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -599,6 +639,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -808,6 +868,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -179,6 +179,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -388,6 +408,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -599,6 +639,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -808,6 +868,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -182,6 +182,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -391,6 +411,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -602,6 +642,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -811,6 +871,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -182,6 +182,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -391,6 +411,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -602,6 +642,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -811,6 +871,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -180,6 +180,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -389,6 +409,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -600,6 +640,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -809,6 +869,26 @@ const example = extrude(10, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
@ -178,6 +178,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -387,6 +407,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -598,6 +638,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
@ -807,6 +867,26 @@ const example = extrude(5, exampleSketch)
|
|||||||
to: [number, number],
|
to: [number, number],
|
||||||
type: "TangentialArc",
|
type: "TangentialArc",
|
||||||
} |
|
} |
|
||||||
|
{
|
||||||
|
// arc's direction
|
||||||
|
ccw: bool,
|
||||||
|
// the arc's center
|
||||||
|
center: [number, number],
|
||||||
|
// The from point.
|
||||||
|
from: [number, number],
|
||||||
|
// the arc's radius
|
||||||
|
radius: number,
|
||||||
|
// The tag of the path.
|
||||||
|
tag: {
|
||||||
|
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||||||
|
end: number,
|
||||||
|
start: number,
|
||||||
|
value: string,
|
||||||
|
},
|
||||||
|
// The to point.
|
||||||
|
to: [number, number],
|
||||||
|
type: "Circle",
|
||||||
|
} |
|
||||||
{
|
{
|
||||||
// The from point.
|
// The from point.
|
||||||
from: [number, number],
|
from: [number, number],
|
||||||
|
216
e2e/playwright/authenticatedAppFixture.ts
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
import type { Page, Locator } from '@playwright/test'
|
||||||
|
import { expect, test as base } from '@playwright/test'
|
||||||
|
import { getUtils, setup, tearDown } from './test-utils'
|
||||||
|
import fsp from 'fs/promises'
|
||||||
|
import { join } from 'path'
|
||||||
|
|
||||||
|
type CmdBarSerilised =
|
||||||
|
| {
|
||||||
|
stage: 'commandBarClosed'
|
||||||
|
// TODO no more properties needed but needs to be implemented in _serialiseCmdBar
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
stage: 'pickCommand'
|
||||||
|
// TODO this will need more properties when implemented in _serialiseCmdBar
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
stage: 'arguments'
|
||||||
|
currentArgKey: string
|
||||||
|
currentArgValue: string
|
||||||
|
headerArguments: Record<string, string>
|
||||||
|
highlightedHeaderArg: string
|
||||||
|
commandName: string
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
stage: 'review'
|
||||||
|
headerArguments: Record<string, string>
|
||||||
|
commandName: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AuthenticatedApp {
|
||||||
|
private readonly codeContent: Locator
|
||||||
|
private readonly extrudeButton: Locator
|
||||||
|
|
||||||
|
constructor(public readonly page: Page) {
|
||||||
|
this.codeContent = page.locator('.cm-content')
|
||||||
|
this.extrudeButton = page.getByTestId('extrude')
|
||||||
|
}
|
||||||
|
|
||||||
|
async initialise(code = '') {
|
||||||
|
const u = await getUtils(this.page)
|
||||||
|
await this.page.addInitScript(async (code) => {
|
||||||
|
localStorage.setItem('persistCode', code)
|
||||||
|
;(window as any).playwrightSkipFilePicker = true
|
||||||
|
}, code)
|
||||||
|
|
||||||
|
await this.page.setViewportSize({ width: 1000, height: 500 })
|
||||||
|
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
}
|
||||||
|
getInputFile = (fileName: string) => {
|
||||||
|
return fsp.readFile(
|
||||||
|
join('src', 'wasm-lib', 'tests', 'executor', 'inputs', fileName),
|
||||||
|
'utf-8'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
makeMouseHelpers = (x: number, y: number) => [
|
||||||
|
() => this.page.mouse.click(x, y),
|
||||||
|
() => this.page.mouse.move(x, y),
|
||||||
|
]
|
||||||
|
|
||||||
|
/** Likely no where, there's a chance it will click something in the scene, depending what you have in the scene.
|
||||||
|
*
|
||||||
|
* Expects the viewPort to be 1000x500 */
|
||||||
|
clickNoWhere = () => this.page.mouse.click(998, 60)
|
||||||
|
|
||||||
|
// Toolbars
|
||||||
|
expectExtrudeButtonToBeDisabled = async () =>
|
||||||
|
await expect(this.extrudeButton).toBeDisabled()
|
||||||
|
expectExtrudeButtonToBeEnabled = async () =>
|
||||||
|
await expect(this.extrudeButton).not.toBeDisabled()
|
||||||
|
clickExtrudeButton = async () => await this.extrudeButton.click()
|
||||||
|
|
||||||
|
private _serialiseCmdBar = async (): Promise<CmdBarSerilised> => {
|
||||||
|
const reviewForm = await this.page.locator('#review-form')
|
||||||
|
const getHeaderArgs = async () => {
|
||||||
|
const inputs = await this.page.getByTestId('cmd-bar-input-tab').all()
|
||||||
|
const entries = await Promise.all(
|
||||||
|
inputs.map((input) => {
|
||||||
|
const key = input
|
||||||
|
.locator('[data-test-name="arg-name"]')
|
||||||
|
.innerText()
|
||||||
|
.then((a) => a.trim())
|
||||||
|
const value = input
|
||||||
|
.getByTestId('header-arg-value')
|
||||||
|
.innerText()
|
||||||
|
.then((a) => a.trim())
|
||||||
|
return Promise.all([key, value])
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return Object.fromEntries(entries)
|
||||||
|
}
|
||||||
|
const getCommandName = () =>
|
||||||
|
this.page.getByTestId('command-name').textContent()
|
||||||
|
if (await reviewForm.isVisible()) {
|
||||||
|
const [headerArguments, commandName] = await Promise.all([
|
||||||
|
getHeaderArgs(),
|
||||||
|
getCommandName(),
|
||||||
|
])
|
||||||
|
return {
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments,
|
||||||
|
commandName: commandName || '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const [
|
||||||
|
currentArgKey,
|
||||||
|
currentArgValue,
|
||||||
|
headerArguments,
|
||||||
|
highlightedHeaderArg,
|
||||||
|
commandName,
|
||||||
|
] = await Promise.all([
|
||||||
|
this.page.getByTestId('cmd-bar-arg-name').textContent(),
|
||||||
|
this.page.getByTestId('cmd-bar-arg-value').textContent(),
|
||||||
|
getHeaderArgs(),
|
||||||
|
this.page
|
||||||
|
.locator('[data-is-current-arg="true"]')
|
||||||
|
.locator('[data-test-name="arg-name"]')
|
||||||
|
.textContent(),
|
||||||
|
getCommandName(),
|
||||||
|
])
|
||||||
|
return {
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: currentArgKey || '',
|
||||||
|
currentArgValue: currentArgValue || '',
|
||||||
|
headerArguments,
|
||||||
|
highlightedHeaderArg: highlightedHeaderArg || '',
|
||||||
|
commandName: commandName || '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectCmdBarToBe = async (expected: CmdBarSerilised) => {
|
||||||
|
return expect.poll(() => this._serialiseCmdBar()).toEqual(expected)
|
||||||
|
}
|
||||||
|
progressCmdBar = async () => {
|
||||||
|
if (Math.random() > 0.5) {
|
||||||
|
const arrowButton = this.page.getByRole('button', {
|
||||||
|
name: 'arrow right Continue',
|
||||||
|
})
|
||||||
|
if (await arrowButton.isVisible()) {
|
||||||
|
await arrowButton.click()
|
||||||
|
} else {
|
||||||
|
await this.page
|
||||||
|
.getByRole('button', { name: 'checkmark Submit command' })
|
||||||
|
.click()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await this.page.keyboard.press('Enter')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectCodeHighlightedToBe = async (code: string) =>
|
||||||
|
await expect
|
||||||
|
.poll(async () => {
|
||||||
|
const texts = (
|
||||||
|
await this.page.getByTestId('hover-highlight').allInnerTexts()
|
||||||
|
).map((s) => s.replace(/\s+/g, '').trim())
|
||||||
|
return texts.join('')
|
||||||
|
})
|
||||||
|
.toBe(code.replace(/\s+/g, '').trim())
|
||||||
|
expectActiveLinesToBe = async (lines: Array<string>) => {
|
||||||
|
await expect
|
||||||
|
.poll(async () => {
|
||||||
|
return (await this.page.locator('.cm-activeLine').allInnerTexts()).map(
|
||||||
|
(l) => l.trim()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.toEqual(lines.map((l) => l.trim()))
|
||||||
|
}
|
||||||
|
private _expectEditorToContain =
|
||||||
|
(not = false) =>
|
||||||
|
(
|
||||||
|
code: string,
|
||||||
|
{
|
||||||
|
shouldNormalise = false,
|
||||||
|
timeout = 5_000,
|
||||||
|
}: { shouldNormalise?: boolean; timeout?: number } = {}
|
||||||
|
) => {
|
||||||
|
if (!shouldNormalise) {
|
||||||
|
const expectStart = expect(this.codeContent)
|
||||||
|
if (not) {
|
||||||
|
return expectStart.not.toContainText(code, { timeout })
|
||||||
|
}
|
||||||
|
return expectStart.toContainText(code, { timeout })
|
||||||
|
}
|
||||||
|
const normalisedCode = code.replaceAll(/\s+/g, ' ').trim()
|
||||||
|
const expectStart = expect.poll(() => this.codeContent.textContent(), {
|
||||||
|
timeout,
|
||||||
|
})
|
||||||
|
if (not) {
|
||||||
|
return expectStart.not.toContain(normalisedCode)
|
||||||
|
}
|
||||||
|
return expectStart.toContain(normalisedCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectEditor = {
|
||||||
|
toContain: this._expectEditorToContain(),
|
||||||
|
not: { toContain: this._expectEditorToContain(true) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const test = base.extend<{
|
||||||
|
app: AuthenticatedApp
|
||||||
|
}>({
|
||||||
|
app: async ({ page }, use) => {
|
||||||
|
const authenticatedApp = new AuthenticatedApp(page)
|
||||||
|
await use(authenticatedApp)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||||
|
await setup(context, page, testInfo)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.afterEach(async ({ page }, testInfo) => {
|
||||||
|
await tearDown(page, testInfo)
|
||||||
|
})
|
||||||
|
|
||||||
|
export { expect } from '@playwright/test'
|
@ -558,7 +558,7 @@ test.describe('Editor tests', () => {
|
|||||||
await page.keyboard.press('ArrowDown')
|
await page.keyboard.press('ArrowDown')
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await page.keyboard.type(`const extrusion = startSketchOn('XY')
|
await page.keyboard.type(`const extrusion = startSketchOn('XY')
|
||||||
|> circle([0, 0], dia/2, %)
|
|> circle({ center: [0, 0], radius: dia/2 }, %)
|
||||||
|> hole(squareHole(length, width, height), %)
|
|> hole(squareHole(length, width, height), %)
|
||||||
|> extrude(height, %)`)
|
|> extrude(height, %)`)
|
||||||
|
|
||||||
|
55
e2e/playwright/point-click.spec.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { test } from './authenticatedAppFixture'
|
||||||
|
|
||||||
|
// test file is for testing point an click code gen functionality that's not sketch mode related
|
||||||
|
|
||||||
|
test('verify extruding circle works', async ({ app }) => {
|
||||||
|
test.skip(
|
||||||
|
process.platform === 'win32',
|
||||||
|
'Fails on windows in CI, can not be replicated locally on windows.'
|
||||||
|
)
|
||||||
|
const file = await app.getInputFile('test-circle-extrude.kcl')
|
||||||
|
await app.initialise(file)
|
||||||
|
const [clickCircle, moveToCircle] = app.makeMouseHelpers(582, 217)
|
||||||
|
|
||||||
|
await test.step('because there is sweepable geometry, verify extrude is enable when nothing is selected', async () => {
|
||||||
|
await app.clickNoWhere()
|
||||||
|
await app.expectExtrudeButtonToBeEnabled()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('check code model connection works and that button is still enable once circle is selected ', async () => {
|
||||||
|
await moveToCircle()
|
||||||
|
const circleSnippet =
|
||||||
|
'circle({ center: [318.33, 168.1], radius: 182.8 }, %)'
|
||||||
|
await app.expectCodeHighlightedToBe(circleSnippet)
|
||||||
|
|
||||||
|
await clickCircle()
|
||||||
|
await app.expectActiveLinesToBe([circleSnippet.slice(-5)])
|
||||||
|
await app.expectExtrudeButtonToBeEnabled()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('do extrude flow and check extrude code is added to editor', async () => {
|
||||||
|
await app.clickExtrudeButton()
|
||||||
|
|
||||||
|
await app.expectCmdBarToBe({
|
||||||
|
stage: 'arguments',
|
||||||
|
currentArgKey: 'distance',
|
||||||
|
currentArgValue: '5',
|
||||||
|
headerArguments: { Selection: '1 face', Distance: '' },
|
||||||
|
highlightedHeaderArg: 'distance',
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await app.progressCmdBar()
|
||||||
|
|
||||||
|
const expectString = 'const extrude001 = extrude(5, sketch001)'
|
||||||
|
await app.expectEditor.not.toContain(expectString)
|
||||||
|
|
||||||
|
await app.expectCmdBarToBe({
|
||||||
|
stage: 'review',
|
||||||
|
headerArguments: { Selection: '1 face', Distance: '5' },
|
||||||
|
commandName: 'Extrude',
|
||||||
|
})
|
||||||
|
await app.progressCmdBar()
|
||||||
|
|
||||||
|
await app.expectEditor.toContain(expectString)
|
||||||
|
})
|
||||||
|
})
|
@ -149,14 +149,16 @@ test.describe('Sketch tests', () => {
|
|||||||
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||||
await page.waitForTimeout(100)
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.mouse.click(700, 200)
|
await expect(async () => {
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
await expect.poll(u.normalisedEditorCode)
|
await expect.poll(u.normalisedEditorCode, { timeout: 1000 })
|
||||||
.toBe(`const sketch001 = startSketchOn('XZ')
|
.toBe(`const sketch001 = startSketchOn('XZ')
|
||||||
|> startProfileAt([12.34, -12.34], %)
|
|> startProfileAt([12.34, -12.34], %)
|
||||||
|> line([-12.34, 12.34], %)
|
|> line([-12.34, 12.34], %)
|
||||||
|
|
||||||
`)
|
`)
|
||||||
|
}).toPass({ timeout: 40_000, intervals: [1_000] })
|
||||||
})
|
})
|
||||||
test('Can exit selection of face', async ({ page }) => {
|
test('Can exit selection of face', async ({ page }) => {
|
||||||
// Load the app with the code panes
|
// Load the app with the code panes
|
||||||
@ -344,6 +346,92 @@ test.describe('Sketch tests', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Can edit a circle center and radius by dragging its handles', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`const sketch001 = startSketchOn('XZ')
|
||||||
|
|> circle({ center: [4.61, -5.01], radius: 8 }, %)`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled()
|
||||||
|
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
|
await u.sendCustomCmd({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_look_at',
|
||||||
|
vantage: { x: 0, y: -1250, z: 580 },
|
||||||
|
center: { x: 0, y: 0, z: 0 },
|
||||||
|
up: { x: 0, y: 0, z: 1 },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await u.sendCustomCmd({
|
||||||
|
type: 'modeling_cmd_req',
|
||||||
|
cmd_id: uuidv4(),
|
||||||
|
cmd: {
|
||||||
|
type: 'default_camera_get_settings',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
const startPX = [667, 325]
|
||||||
|
|
||||||
|
const dragPX = 40
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByText('circle({ center: [4.61, -5.01], radius: 8 }, %)')
|
||||||
|
.click()
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Edit Sketch' })
|
||||||
|
).toBeVisible()
|
||||||
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
|
await page.waitForTimeout(400)
|
||||||
|
let prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
|
||||||
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(1)
|
||||||
|
|
||||||
|
await test.step('drag circle center handle', async () => {
|
||||||
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
|
sourcePosition: { x: startPX[0], y: startPX[1] },
|
||||||
|
targetPosition: { x: startPX[0] + dragPX, y: startPX[1] - dragPX },
|
||||||
|
})
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('drag circle radius handle', async () => {
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
|
const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]')
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.dragAndDrop('#stream', '#stream', {
|
||||||
|
sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y },
|
||||||
|
targetPosition: { x: lineEnd.x + dragPX * 2, y: lineEnd.y + dragPX },
|
||||||
|
})
|
||||||
|
await expect(page.locator('.cm-content')).not.toHaveText(prevContent)
|
||||||
|
prevContent = await page.locator('.cm-content').innerText()
|
||||||
|
})
|
||||||
|
|
||||||
|
// expect the code to have changed
|
||||||
|
await expect(page.locator('.cm-content'))
|
||||||
|
.toHaveText(`const sketch001 = startSketchOn('XZ')
|
||||||
|
|> circle({ center: [7.26, -2.37], radius: 11.44 }, %)
|
||||||
|
`)
|
||||||
|
})
|
||||||
test('Can edit a sketch that has been extruded in the same pipe', async ({
|
test('Can edit a sketch that has been extruded in the same pipe', async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -532,6 +532,64 @@ test(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
test(
|
||||||
|
'Draft circle should look right',
|
||||||
|
{ tag: '@snapshot' },
|
||||||
|
async ({ page, context }) => {
|
||||||
|
// FIXME: Skip on macos its being weird.
|
||||||
|
// test.skip(process.platform === 'darwin', 'Skip on macos')
|
||||||
|
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
const PUR = 400 / 37.5 //pixeltoUnitRatio
|
||||||
|
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
await u.openDebugPanel()
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).not.toBeDisabled()
|
||||||
|
await expect(
|
||||||
|
page.getByRole('button', { name: 'Start Sketch' })
|
||||||
|
).toBeVisible()
|
||||||
|
|
||||||
|
// click on "Start Sketch" button
|
||||||
|
await u.clearCommandLogs()
|
||||||
|
await u.doAndWaitForImageDiff(
|
||||||
|
() => page.getByRole('button', { name: 'Start Sketch' }).click(),
|
||||||
|
200
|
||||||
|
)
|
||||||
|
|
||||||
|
// select a plane
|
||||||
|
await page.mouse.click(700, 200)
|
||||||
|
|
||||||
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
|
`const sketch001 = startSketchOn('XZ')`
|
||||||
|
)
|
||||||
|
|
||||||
|
await page.waitForTimeout(500) // TODO detect animation ending, or disable animation
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
const startXPx = 600
|
||||||
|
|
||||||
|
// Equip the rectangle tool
|
||||||
|
// await page.getByRole('button', { name: 'line Line', exact: true }).click()
|
||||||
|
await page.getByTestId('circle-center').click()
|
||||||
|
|
||||||
|
// Draw the rectangle
|
||||||
|
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20)
|
||||||
|
await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 10, { steps: 5 })
|
||||||
|
|
||||||
|
// Ensure the draft rectangle looks the same as it usually does
|
||||||
|
await expect(page).toHaveScreenshot({
|
||||||
|
maxDiffPixels: 100,
|
||||||
|
})
|
||||||
|
await expect(page.locator('.cm-content')).toHaveText(
|
||||||
|
`const sketch001 = startSketchOn('XZ')
|
||||||
|
|> circle({ center: [14.44, -2.44], radius: 1 }, %)`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
test.describe(
|
test.describe(
|
||||||
'Client side scene scale should match engine scale',
|
'Client side scene scale should match engine scale',
|
||||||
|
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 38 KiB |
@ -365,10 +365,10 @@ const box = startSketchOn('XY')
|
|||||||
svg(startSketchOn(keychain, 'end'), [-33, 32], -thickness)
|
svg(startSketchOn(keychain, 'end'), [-33, 32], -thickness)
|
||||||
|
|
||||||
startSketchOn(keychain, 'end')
|
startSketchOn(keychain, 'end')
|
||||||
|> circle([
|
|> circle({ center: [
|
||||||
width / 2,
|
width / 2,
|
||||||
height - (keychainHoleSize + 1.5)
|
height - (keychainHoleSize + 1.5)
|
||||||
], keychainHoleSize, %)
|
], radius: keychainHoleSize }, %)
|
||||||
|> extrude(-thickness, %)`
|
|> extrude(-thickness, %)`
|
||||||
|
|
||||||
export const TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR = `const thing = 1`
|
export const TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR = `const thing = 1`
|
||||||
|
@ -774,6 +774,80 @@ const part001 = startSketchOn('XZ')
|
|||||||
locator: '[data-overlay-toolbar-index="12"]',
|
locator: '[data-overlay-toolbar-index="12"]',
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
test('for segment [circle]', async ({ page }) => {
|
||||||
|
await page.addInitScript(async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'persistCode',
|
||||||
|
`const part001 = startSketchOn('XZ')
|
||||||
|
|> circle({ center: [1 + 0, 0], radius: 8 }, %)
|
||||||
|
`
|
||||||
|
)
|
||||||
|
localStorage.setItem('disableAxis', 'true')
|
||||||
|
})
|
||||||
|
const u = await getUtils(page)
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
// wait for execution done
|
||||||
|
await u.openDebugPanel()
|
||||||
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
|
await u.closeDebugPanel()
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByText('circle({ center: [1 + 0, 0], radius: 8 }, %)')
|
||||||
|
.click()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
await page.getByRole('button', { name: 'Edit Sketch' }).click()
|
||||||
|
await page.waitForTimeout(500)
|
||||||
|
|
||||||
|
await expect(page.getByTestId('segment-overlay')).toHaveCount(1)
|
||||||
|
|
||||||
|
const clickUnconstrained = _clickUnconstrained(page)
|
||||||
|
const clickConstrained = _clickConstrained(page)
|
||||||
|
|
||||||
|
const hoverPos = { x: 789, y: 114 } as const
|
||||||
|
let ang = await u.getAngle('[data-overlay-index="0"]')
|
||||||
|
console.log('angl', ang)
|
||||||
|
console.log('circle center x')
|
||||||
|
await clickConstrained({
|
||||||
|
hoverPos,
|
||||||
|
constraintType: 'xAbsolute',
|
||||||
|
expectBeforeUnconstrained:
|
||||||
|
'circle({ center: [1 + 0, 0], radius: 8 }, %)',
|
||||||
|
expectAfterUnconstrained: 'circle({ center: [1, 0], radius: 8 }, %)',
|
||||||
|
expectFinal: 'circle({ center: [xAbs001, 0], radius: 8 }, %)',
|
||||||
|
ang: ang + 105,
|
||||||
|
steps: 6,
|
||||||
|
locator: '[data-overlay-toolbar-index="0"]',
|
||||||
|
})
|
||||||
|
console.log('circle center y')
|
||||||
|
await clickUnconstrained({
|
||||||
|
hoverPos,
|
||||||
|
constraintType: 'yAbsolute',
|
||||||
|
expectBeforeUnconstrained:
|
||||||
|
'circle({ center: [xAbs001, 0], radius: 8 }, %)',
|
||||||
|
expectAfterUnconstrained:
|
||||||
|
'circle({ center: [xAbs001, yAbs001], radius: 8 }, %)',
|
||||||
|
expectFinal: 'circle({ center: [xAbs001, 0], radius: 8 }, %)',
|
||||||
|
ang: ang + 105,
|
||||||
|
steps: 10,
|
||||||
|
locator: '[data-overlay-toolbar-index="0"]',
|
||||||
|
})
|
||||||
|
console.log('circle radius')
|
||||||
|
await clickUnconstrained({
|
||||||
|
hoverPos,
|
||||||
|
constraintType: 'radius',
|
||||||
|
expectBeforeUnconstrained:
|
||||||
|
'circle({ center: [xAbs001, 0], radius: 8 }, %)',
|
||||||
|
expectAfterUnconstrained:
|
||||||
|
'circle({ center: [xAbs001, 0], radius: radius001 }, %)',
|
||||||
|
expectFinal: 'circle({ center: [xAbs001, 0], radius: 8 }, %)',
|
||||||
|
ang: ang + 105,
|
||||||
|
steps: 10,
|
||||||
|
locator: '[data-overlay-toolbar-index="0"]',
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
test.describe('Testing deleting a segment', () => {
|
test.describe('Testing deleting a segment', () => {
|
||||||
const _deleteSegmentSequence =
|
const _deleteSegmentSequence =
|
||||||
|
@ -96,15 +96,29 @@ export const ClientSideScene = ({
|
|||||||
canvas.appendChild(sceneInfra.renderer.domElement)
|
canvas.appendChild(sceneInfra.renderer.domElement)
|
||||||
canvas.appendChild(sceneInfra.labelRenderer.domElement)
|
canvas.appendChild(sceneInfra.labelRenderer.domElement)
|
||||||
sceneInfra.animate()
|
sceneInfra.animate()
|
||||||
canvas.addEventListener('mousemove', sceneInfra.onMouseMove, false)
|
canvas.addEventListener(
|
||||||
|
'mousemove',
|
||||||
|
toSync(sceneInfra.onMouseMove, reportRejection),
|
||||||
|
false
|
||||||
|
)
|
||||||
canvas.addEventListener('mousedown', sceneInfra.onMouseDown, false)
|
canvas.addEventListener('mousedown', sceneInfra.onMouseDown, false)
|
||||||
canvas.addEventListener('mouseup', sceneInfra.onMouseUp, false)
|
canvas.addEventListener(
|
||||||
|
'mouseup',
|
||||||
|
toSync(sceneInfra.onMouseUp, reportRejection),
|
||||||
|
false
|
||||||
|
)
|
||||||
sceneInfra.setSend(send)
|
sceneInfra.setSend(send)
|
||||||
engineCommandManager.modelingSend = send
|
engineCommandManager.modelingSend = send
|
||||||
return () => {
|
return () => {
|
||||||
canvas?.removeEventListener('mousemove', sceneInfra.onMouseMove)
|
canvas?.removeEventListener(
|
||||||
|
'mousemove',
|
||||||
|
toSync(sceneInfra.onMouseMove, reportRejection)
|
||||||
|
)
|
||||||
canvas?.removeEventListener('mousedown', sceneInfra.onMouseDown)
|
canvas?.removeEventListener('mousedown', sceneInfra.onMouseDown)
|
||||||
canvas?.removeEventListener('mouseup', sceneInfra.onMouseUp)
|
canvas?.removeEventListener(
|
||||||
|
'mouseup',
|
||||||
|
toSync(sceneInfra.onMouseUp, reportRejection)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@ -124,7 +138,8 @@ export const ClientSideScene = ({
|
|||||||
} else if (
|
} else if (
|
||||||
state.matches({ Sketch: 'Line tool' }) ||
|
state.matches({ Sketch: 'Line tool' }) ||
|
||||||
state.matches({ Sketch: 'Tangential arc to' }) ||
|
state.matches({ Sketch: 'Tangential arc to' }) ||
|
||||||
state.matches({ Sketch: 'Rectangle tool' })
|
state.matches({ Sketch: 'Rectangle tool' }) ||
|
||||||
|
state.matches({ Sketch: 'Circle tool' })
|
||||||
) {
|
) {
|
||||||
cursor = 'crosshair'
|
cursor = 'crosshair'
|
||||||
} else {
|
} else {
|
||||||
@ -269,15 +284,22 @@ const Overlay = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<SegmentMenu
|
{/* delete circle is complicated by the fact it's the only segment in the
|
||||||
verticalPosition={
|
pipe expression. Maybe it should delete the entire pipeExpression, however
|
||||||
overlay.windowCoords[1] > window.innerHeight / 2
|
this will likely change soon when we implement multi-profile so we'll leave it for now
|
||||||
? 'top'
|
issue: https://github.com/KittyCAD/modeling-app/issues/3910
|
||||||
: 'bottom'
|
*/}
|
||||||
}
|
{callExpression?.callee?.name !== 'circle' && (
|
||||||
pathToNode={overlay.pathToNode}
|
<SegmentMenu
|
||||||
stdLibFnName={constraints[0]?.stdLibFnName}
|
verticalPosition={
|
||||||
/>
|
overlay.windowCoords[1] > window.innerHeight / 2
|
||||||
|
? 'top'
|
||||||
|
: 'bottom'
|
||||||
|
}
|
||||||
|
pathToNode={overlay.pathToNode}
|
||||||
|
stdLibFnName={constraints[0]?.stdLibFnName}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -512,6 +534,11 @@ const ConstraintSymbol = ({
|
|||||||
displayName: 'Intersection Offset',
|
displayName: 'Intersection Offset',
|
||||||
iconName: 'intersection-offset',
|
iconName: 'intersection-offset',
|
||||||
},
|
},
|
||||||
|
radius: {
|
||||||
|
varName: 'radius',
|
||||||
|
displayName: 'Radius',
|
||||||
|
iconName: 'dimension',
|
||||||
|
},
|
||||||
|
|
||||||
// implicit constraints
|
// implicit constraints
|
||||||
vertical: {
|
vertical: {
|
||||||
|
@ -72,6 +72,7 @@ import {
|
|||||||
createArrayExpression,
|
createArrayExpression,
|
||||||
createCallExpressionStdLib,
|
createCallExpressionStdLib,
|
||||||
createLiteral,
|
createLiteral,
|
||||||
|
createObjectExpression,
|
||||||
createPipeExpression,
|
createPipeExpression,
|
||||||
createPipeSubstitution,
|
createPipeSubstitution,
|
||||||
findUniqueName,
|
findUniqueName,
|
||||||
@ -90,6 +91,7 @@ import { getThemeColorForThreeJs, Themes } from 'lib/theme'
|
|||||||
import { err, reportRejection, trap } from 'lib/trap'
|
import { err, reportRejection, trap } from 'lib/trap'
|
||||||
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
||||||
import { Point3d } from 'wasm-lib/kcl/bindings/Point3d'
|
import { Point3d } from 'wasm-lib/kcl/bindings/Point3d'
|
||||||
|
import { SegmentInputs } from 'lang/std/stdTypes'
|
||||||
|
|
||||||
type DraftSegment = 'line' | 'tangentialArcTo'
|
type DraftSegment = 'line' | 'tangentialArcTo'
|
||||||
|
|
||||||
@ -103,10 +105,18 @@ export const TANGENTIAL_ARC_TO__SEGMENT_DASH =
|
|||||||
'tangential-arc-to-segment-body-dashed'
|
'tangential-arc-to-segment-body-dashed'
|
||||||
export const TANGENTIAL_ARC_TO_SEGMENT = 'tangential-arc-to-segment'
|
export const TANGENTIAL_ARC_TO_SEGMENT = 'tangential-arc-to-segment'
|
||||||
export const TANGENTIAL_ARC_TO_SEGMENT_BODY = 'tangential-arc-to-segment-body'
|
export const TANGENTIAL_ARC_TO_SEGMENT_BODY = 'tangential-arc-to-segment-body'
|
||||||
|
export const CIRCLE_SEGMENT = 'circle-segment'
|
||||||
|
export const CIRCLE_SEGMENT_BODY = 'circle-segment-body'
|
||||||
|
export const CIRCLE_SEGMENT_DASH = 'circle-segment-body-dashed'
|
||||||
|
export const CIRCLE_CENTER_HANDLE = 'circle-center-handle'
|
||||||
export const SEGMENT_WIDTH_PX = 1.6
|
export const SEGMENT_WIDTH_PX = 1.6
|
||||||
export const HIDE_SEGMENT_LENGTH = 75 // in pixels
|
export const HIDE_SEGMENT_LENGTH = 75 // in pixels
|
||||||
export const HIDE_HOVER_SEGMENT_LENGTH = 60 // in pixels
|
export const HIDE_HOVER_SEGMENT_LENGTH = 60 // in pixels
|
||||||
export const SEGMENT_BODIES = [STRAIGHT_SEGMENT, TANGENTIAL_ARC_TO_SEGMENT]
|
export const SEGMENT_BODIES = [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
CIRCLE_SEGMENT,
|
||||||
|
]
|
||||||
export const SEGMENT_BODIES_PLUS_PROFILE_START = [
|
export const SEGMENT_BODIES_PLUS_PROFILE_START = [
|
||||||
...SEGMENT_BODIES,
|
...SEGMENT_BODIES,
|
||||||
PROFILE_START,
|
PROFILE_START,
|
||||||
@ -144,11 +154,11 @@ export class SceneEntities {
|
|||||||
? orthoFactor
|
? orthoFactor
|
||||||
: perspScale(sceneInfra.camControls.camera, segment)) /
|
: perspScale(sceneInfra.camControls.camera, segment)) /
|
||||||
sceneInfra._baseUnitMultiplier
|
sceneInfra._baseUnitMultiplier
|
||||||
const input = {
|
let input: SegmentInputs = {
|
||||||
type: 'straight-segment',
|
type: 'straight-segment',
|
||||||
from: segment.userData.from,
|
from: segment.userData.from,
|
||||||
to: segment.userData.to,
|
to: segment.userData.to,
|
||||||
} as const
|
}
|
||||||
let update: SegmentUtils['update'] | null = null
|
let update: SegmentUtils['update'] | null = null
|
||||||
if (
|
if (
|
||||||
segment.userData.from &&
|
segment.userData.from &&
|
||||||
@ -165,6 +175,21 @@ export class SceneEntities {
|
|||||||
) {
|
) {
|
||||||
update = segmentUtils.tangentialArcTo.update
|
update = segmentUtils.tangentialArcTo.update
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
segment.userData.from &&
|
||||||
|
segment.userData.center &&
|
||||||
|
segment.userData.radius &&
|
||||||
|
segment.userData.type === CIRCLE_SEGMENT
|
||||||
|
) {
|
||||||
|
update = segmentUtils.circle.update
|
||||||
|
input = {
|
||||||
|
type: 'arc-segment',
|
||||||
|
from: segment.userData.from,
|
||||||
|
center: segment.userData.center,
|
||||||
|
radius: segment.userData.radius,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const callBack = update?.({
|
const callBack = update?.({
|
||||||
prevSegment: segment.userData.prevSegment,
|
prevSegment: segment.userData.prevSegment,
|
||||||
input,
|
input,
|
||||||
@ -311,7 +336,6 @@ export class SceneEntities {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
onClick: async (args) => {
|
onClick: async (args) => {
|
||||||
if (!args) return
|
if (!args) return
|
||||||
if (args.mouseEvent.which !== 1) return
|
if (args.mouseEvent.which !== 1) return
|
||||||
@ -409,19 +433,21 @@ export class SceneEntities {
|
|||||||
maybeModdedAst,
|
maybeModdedAst,
|
||||||
sketchGroup.start.__geoMeta.sourceRange
|
sketchGroup.start.__geoMeta.sourceRange
|
||||||
)
|
)
|
||||||
const _profileStart = createProfileStartHandle({
|
if (sketchGroup?.value?.[0]?.type !== 'Circle') {
|
||||||
from: sketchGroup.start.from,
|
const _profileStart = createProfileStartHandle({
|
||||||
id: sketchGroup.start.__geoMeta.id,
|
from: sketchGroup.start.from,
|
||||||
pathToNode: segPathToNode,
|
id: sketchGroup.start.__geoMeta.id,
|
||||||
scale: factor,
|
pathToNode: segPathToNode,
|
||||||
theme: sceneInfra._theme,
|
scale: factor,
|
||||||
})
|
theme: sceneInfra._theme,
|
||||||
_profileStart.layers.set(SKETCH_LAYER)
|
})
|
||||||
_profileStart.traverse((child) => {
|
_profileStart.layers.set(SKETCH_LAYER)
|
||||||
child.layers.set(SKETCH_LAYER)
|
_profileStart.traverse((child) => {
|
||||||
})
|
child.layers.set(SKETCH_LAYER)
|
||||||
group.add(_profileStart)
|
})
|
||||||
this.activeSegments[JSON.stringify(segPathToNode)] = _profileStart
|
group.add(_profileStart)
|
||||||
|
this.activeSegments[JSON.stringify(segPathToNode)] = _profileStart
|
||||||
|
}
|
||||||
const callbacks: (() => SegmentOverlayPayload | null)[] = []
|
const callbacks: (() => SegmentOverlayPayload | null)[] = []
|
||||||
sketchGroup.value.forEach((segment, index) => {
|
sketchGroup.value.forEach((segment, index) => {
|
||||||
let segPathToNode = getNodePathFromSourceRange(
|
let segPathToNode = getNodePathFromSourceRange(
|
||||||
@ -467,15 +493,26 @@ export class SceneEntities {
|
|||||||
const initSegment =
|
const initSegment =
|
||||||
segment.type === 'TangentialArcTo'
|
segment.type === 'TangentialArcTo'
|
||||||
? segmentUtils.tangentialArcTo.init
|
? segmentUtils.tangentialArcTo.init
|
||||||
|
: segment.type === 'Circle'
|
||||||
|
? segmentUtils.circle.init
|
||||||
: segmentUtils.straight.init
|
: segmentUtils.straight.init
|
||||||
|
const input: SegmentInputs =
|
||||||
|
segment.type === 'Circle'
|
||||||
|
? {
|
||||||
|
type: 'arc-segment',
|
||||||
|
from: segment.from,
|
||||||
|
center: segment.center,
|
||||||
|
radius: segment.radius,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: 'straight-segment',
|
||||||
|
from: segment.from,
|
||||||
|
to: segment.to,
|
||||||
|
}
|
||||||
const result = initSegment({
|
const result = initSegment({
|
||||||
prevSegment: sketchGroup.value[index - 1],
|
prevSegment: sketchGroup.value[index - 1],
|
||||||
callExpName,
|
callExpName,
|
||||||
input: {
|
input,
|
||||||
type: 'straight-segment',
|
|
||||||
from: segment.from,
|
|
||||||
to: segment.to,
|
|
||||||
},
|
|
||||||
id: segment.__geoMeta.id,
|
id: segment.__geoMeta.id,
|
||||||
pathToNode: segPathToNode,
|
pathToNode: segPathToNode,
|
||||||
isDraftSegment,
|
isDraftSegment,
|
||||||
@ -575,7 +612,6 @@ export class SceneEntities {
|
|||||||
const lastSeg = sg?.value?.slice(-1)[0] || sg.start
|
const lastSeg = sg?.value?.slice(-1)[0] || sg.start
|
||||||
|
|
||||||
const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1`
|
const index = sg.value.length // because we've added a new segment that's not in the memory yet, no need for `-1`
|
||||||
|
|
||||||
const mod = addNewSketchLn({
|
const mod = addNewSketchLn({
|
||||||
node: _ast,
|
node: _ast,
|
||||||
programMemory: kclManager.programMemory,
|
programMemory: kclManager.programMemory,
|
||||||
@ -606,7 +642,6 @@ export class SceneEntities {
|
|||||||
draftExpressionsIndices,
|
draftExpressionsIndices,
|
||||||
})
|
})
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
onClick: async (args) => {
|
onClick: async (args) => {
|
||||||
if (!args) return
|
if (!args) return
|
||||||
if (args.mouseEvent.which !== 1) return
|
if (args.mouseEvent.which !== 1) return
|
||||||
@ -747,7 +782,6 @@ export class SceneEntities {
|
|||||||
})
|
})
|
||||||
|
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
onMove: async (args) => {
|
onMove: async (args) => {
|
||||||
// Update the width and height of the draft rectangle
|
// Update the width and height of the draft rectangle
|
||||||
const pathToNodeTwo = structuredClone(sketchPathToNode)
|
const pathToNodeTwo = structuredClone(sketchPathToNode)
|
||||||
@ -779,7 +813,7 @@ export class SceneEntities {
|
|||||||
programMemory.get(variableDeclarationName),
|
programMemory.get(variableDeclarationName),
|
||||||
variableDeclarationName
|
variableDeclarationName
|
||||||
)
|
)
|
||||||
if (err(sketchGroup)) return sketchGroup
|
if (err(sketchGroup)) return Promise.reject(sketchGroup)
|
||||||
const sgPaths = sketchGroup.value
|
const sgPaths = sketchGroup.value
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
@ -795,7 +829,6 @@ export class SceneEntities {
|
|||||||
this.updateSegment(seg, index, 0, _ast, orthoFactor, sketchGroup)
|
this.updateSegment(seg, index, 0, _ast, orthoFactor, sketchGroup)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
onClick: async (args) => {
|
onClick: async (args) => {
|
||||||
// Commit the rectangle to the full AST/code and return to sketch.idle
|
// Commit the rectangle to the full AST/code and return to sketch.idle
|
||||||
const cornerPoint = args.intersectionPoint?.twoD
|
const cornerPoint = args.intersectionPoint?.twoD
|
||||||
@ -857,6 +890,173 @@ export class SceneEntities {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
setupDraftCircle = async (
|
||||||
|
sketchPathToNode: PathToNode,
|
||||||
|
forward: [number, number, number],
|
||||||
|
up: [number, number, number],
|
||||||
|
sketchOrigin: [number, number, number],
|
||||||
|
circleCenter: [x: number, y: number]
|
||||||
|
) => {
|
||||||
|
let _ast = structuredClone(kclManager.ast)
|
||||||
|
|
||||||
|
const _node1 = getNodeFromPath<VariableDeclaration>(
|
||||||
|
_ast,
|
||||||
|
sketchPathToNode || [],
|
||||||
|
'VariableDeclaration'
|
||||||
|
)
|
||||||
|
if (trap(_node1)) return Promise.reject(_node1)
|
||||||
|
const variableDeclarationName =
|
||||||
|
_node1.node?.declarations?.[0]?.id?.name || ''
|
||||||
|
const startSketchOn = _node1.node?.declarations
|
||||||
|
const startSketchOnInit = startSketchOn?.[0]?.init
|
||||||
|
|
||||||
|
startSketchOn[0].init = createPipeExpression([
|
||||||
|
startSketchOnInit,
|
||||||
|
createCallExpressionStdLib('circle', [
|
||||||
|
createObjectExpression({
|
||||||
|
center: createArrayExpression([
|
||||||
|
createLiteral(roundOff(circleCenter[0])),
|
||||||
|
createLiteral(roundOff(circleCenter[1])),
|
||||||
|
]),
|
||||||
|
radius: createLiteral(1),
|
||||||
|
}),
|
||||||
|
createPipeSubstitution(),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
|
||||||
|
let _recastAst = parse(recast(_ast))
|
||||||
|
if (trap(_recastAst)) return Promise.reject(_recastAst)
|
||||||
|
_ast = _recastAst
|
||||||
|
|
||||||
|
// do a quick mock execution to get the program memory up-to-date
|
||||||
|
await kclManager.executeAstMock(_ast)
|
||||||
|
|
||||||
|
const { programMemoryOverride, truncatedAst } = await this.setupSketch({
|
||||||
|
sketchPathToNode,
|
||||||
|
forward,
|
||||||
|
up,
|
||||||
|
position: sketchOrigin,
|
||||||
|
maybeModdedAst: _ast,
|
||||||
|
draftExpressionsIndices: { start: 0, end: 0 },
|
||||||
|
})
|
||||||
|
|
||||||
|
sceneInfra.setCallbacks({
|
||||||
|
onMove: async (args) => {
|
||||||
|
const pathToNodeTwo = structuredClone(sketchPathToNode)
|
||||||
|
pathToNodeTwo[1][0] = 0
|
||||||
|
|
||||||
|
const _node = getNodeFromPath<VariableDeclaration>(
|
||||||
|
truncatedAst,
|
||||||
|
pathToNodeTwo || [],
|
||||||
|
'VariableDeclaration'
|
||||||
|
)
|
||||||
|
let modded = structuredClone(truncatedAst)
|
||||||
|
if (trap(_node)) return
|
||||||
|
const sketchInit = _node.node?.declarations?.[0]?.init
|
||||||
|
|
||||||
|
const x = (args.intersectionPoint.twoD.x || 0) - circleCenter[0]
|
||||||
|
const y = (args.intersectionPoint.twoD.y || 0) - circleCenter[1]
|
||||||
|
|
||||||
|
if (sketchInit.type === 'PipeExpression') {
|
||||||
|
const moddedResult = changeSketchArguments(
|
||||||
|
modded,
|
||||||
|
kclManager.programMemory,
|
||||||
|
{
|
||||||
|
type: 'path',
|
||||||
|
pathToNode: [
|
||||||
|
..._node.deepPath,
|
||||||
|
['body', 'PipeExpression'],
|
||||||
|
[1, 'index'],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'arc-segment',
|
||||||
|
center: circleCenter,
|
||||||
|
radius: Math.sqrt(x ** 2 + y ** 2),
|
||||||
|
from: circleCenter,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (err(moddedResult)) return
|
||||||
|
modded = moddedResult.modifiedAst
|
||||||
|
}
|
||||||
|
|
||||||
|
const { programMemory } = await executeAst({
|
||||||
|
ast: modded,
|
||||||
|
useFakeExecutor: true,
|
||||||
|
engineCommandManager: this.engineCommandManager,
|
||||||
|
programMemoryOverride,
|
||||||
|
})
|
||||||
|
this.sceneProgramMemory = programMemory
|
||||||
|
const sketchGroup = sketchGroupFromKclValue(
|
||||||
|
programMemory.get(variableDeclarationName),
|
||||||
|
variableDeclarationName
|
||||||
|
)
|
||||||
|
if (err(sketchGroup)) return
|
||||||
|
const sgPaths = sketchGroup.value
|
||||||
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
|
this.updateSegment(
|
||||||
|
sketchGroup.start,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
_ast,
|
||||||
|
orthoFactor,
|
||||||
|
sketchGroup
|
||||||
|
)
|
||||||
|
sgPaths.forEach((seg, index) =>
|
||||||
|
this.updateSegment(seg, index, 0, _ast, orthoFactor, sketchGroup)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick: async (args) => {
|
||||||
|
// Commit the rectangle to the full AST/code and return to sketch.idle
|
||||||
|
const cornerPoint = args.intersectionPoint?.twoD
|
||||||
|
if (!cornerPoint || args.mouseEvent.button !== 0) return
|
||||||
|
|
||||||
|
const x = roundOff((cornerPoint.x || 0) - circleCenter[0])
|
||||||
|
const y = roundOff((cornerPoint.y || 0) - circleCenter[1])
|
||||||
|
|
||||||
|
const _node = getNodeFromPath<VariableDeclaration>(
|
||||||
|
_ast,
|
||||||
|
sketchPathToNode || [],
|
||||||
|
'VariableDeclaration'
|
||||||
|
)
|
||||||
|
if (trap(_node)) return
|
||||||
|
const sketchInit = _node.node?.declarations?.[0]?.init
|
||||||
|
|
||||||
|
let modded = structuredClone(_ast)
|
||||||
|
if (sketchInit.type === 'PipeExpression') {
|
||||||
|
const moddedResult = changeSketchArguments(
|
||||||
|
modded,
|
||||||
|
kclManager.programMemory,
|
||||||
|
{
|
||||||
|
type: 'path',
|
||||||
|
pathToNode: [
|
||||||
|
..._node.deepPath,
|
||||||
|
['body', 'PipeExpression'],
|
||||||
|
[1, 'index'],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'arc-segment',
|
||||||
|
center: circleCenter,
|
||||||
|
radius: Math.sqrt(x ** 2 + y ** 2),
|
||||||
|
from: circleCenter,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (err(moddedResult)) return
|
||||||
|
modded = moddedResult.modifiedAst
|
||||||
|
|
||||||
|
let _recastAst = parse(recast(modded))
|
||||||
|
if (trap(_recastAst)) return Promise.reject(_recastAst)
|
||||||
|
_ast = _recastAst
|
||||||
|
|
||||||
|
// Update the primary AST and unequip the rectangle tool
|
||||||
|
await kclManager.executeAstMock(_ast)
|
||||||
|
sceneInfra.modelingSend({ type: 'Finish circle' })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
setupSketchIdleCallbacks = ({
|
setupSketchIdleCallbacks = ({
|
||||||
pathToNode,
|
pathToNode,
|
||||||
up,
|
up,
|
||||||
@ -870,7 +1070,6 @@ export class SceneEntities {
|
|||||||
}) => {
|
}) => {
|
||||||
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
let addingNewSegmentStatus: 'nothing' | 'pending' | 'added' = 'nothing'
|
||||||
sceneInfra.setCallbacks({
|
sceneInfra.setCallbacks({
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
onDragEnd: async () => {
|
onDragEnd: async () => {
|
||||||
if (addingNewSegmentStatus !== 'nothing') {
|
if (addingNewSegmentStatus !== 'nothing') {
|
||||||
await this.tearDownSketch({ removeAxis: false })
|
await this.tearDownSketch({ removeAxis: false })
|
||||||
@ -891,7 +1090,6 @@ export class SceneEntities {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
||||||
onDrag: async ({
|
onDrag: async ({
|
||||||
selected,
|
selected,
|
||||||
intersectionPoint,
|
intersectionPoint,
|
||||||
@ -1028,11 +1226,8 @@ export class SceneEntities {
|
|||||||
? new Vector2(profileStart.position.x, profileStart.position.y)
|
? new Vector2(profileStart.position.x, profileStart.position.y)
|
||||||
: _intersection2d
|
: _intersection2d
|
||||||
|
|
||||||
const group = getParentGroup(object, [
|
const group = getParentGroup(object, SEGMENT_BODIES_PLUS_PROFILE_START)
|
||||||
STRAIGHT_SEGMENT,
|
const subGroup = getParentGroup(object, [ARROWHEAD, CIRCLE_CENTER_HANDLE])
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
|
||||||
PROFILE_START,
|
|
||||||
])
|
|
||||||
if (!group) return
|
if (!group) return
|
||||||
const pathToNode: PathToNode = structuredClone(group.userData.pathToNode)
|
const pathToNode: PathToNode = structuredClone(group.userData.pathToNode)
|
||||||
const varDecIndex = pathToNode[1][0]
|
const varDecIndex = pathToNode[1][0]
|
||||||
@ -1069,6 +1264,43 @@ export class SceneEntities {
|
|||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
}
|
}
|
||||||
| Error
|
| Error
|
||||||
|
|
||||||
|
const getChangeSketchInput = (): SegmentInputs => {
|
||||||
|
if (
|
||||||
|
group.name === CIRCLE_SEGMENT &&
|
||||||
|
// !subGroup treats grabbing the outer circumference of the circle
|
||||||
|
// as a drag of the center handle
|
||||||
|
(!subGroup || subGroup?.name === ARROWHEAD)
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
type: 'arc-segment',
|
||||||
|
from,
|
||||||
|
center: group.userData.center,
|
||||||
|
// distance between the center and the drag point
|
||||||
|
radius: Math.sqrt(
|
||||||
|
(group.userData.center[0] - dragTo[0]) ** 2 +
|
||||||
|
(group.userData.center[1] - dragTo[1]) ** 2
|
||||||
|
),
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
group.name === CIRCLE_SEGMENT &&
|
||||||
|
subGroup?.name === CIRCLE_CENTER_HANDLE
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
type: 'arc-segment',
|
||||||
|
from,
|
||||||
|
center: dragTo,
|
||||||
|
radius: group.userData.radius,
|
||||||
|
}
|
||||||
|
|
||||||
|
// straight segment is the default
|
||||||
|
return {
|
||||||
|
type: 'straight-segment',
|
||||||
|
from,
|
||||||
|
to: dragTo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (group.name === PROFILE_START) {
|
if (group.name === PROFILE_START) {
|
||||||
modded = updateStartProfileAtArgs({
|
modded = updateStartProfileAtArgs({
|
||||||
node: modifiedAst,
|
node: modifiedAst,
|
||||||
@ -1084,12 +1316,11 @@ export class SceneEntities {
|
|||||||
modded = changeSketchArguments(
|
modded = changeSketchArguments(
|
||||||
modifiedAst,
|
modifiedAst,
|
||||||
kclManager.programMemory,
|
kclManager.programMemory,
|
||||||
[node.start, node.end],
|
|
||||||
{
|
{
|
||||||
type: 'straight-segment',
|
type: 'sourceRange',
|
||||||
from,
|
sourceRange: [node.start, node.end],
|
||||||
to: dragTo,
|
},
|
||||||
}
|
getChangeSketchInput()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (trap(modded)) return
|
if (trap(modded)) return
|
||||||
@ -1192,16 +1423,28 @@ export class SceneEntities {
|
|||||||
? orthoFactor
|
? orthoFactor
|
||||||
: perspScale(sceneInfra.camControls.camera, group)) /
|
: perspScale(sceneInfra.camControls.camera, group)) /
|
||||||
sceneInfra._baseUnitMultiplier
|
sceneInfra._baseUnitMultiplier
|
||||||
const input = {
|
let input: SegmentInputs = {
|
||||||
type: 'straight-segment',
|
type: 'straight-segment',
|
||||||
from: segment.from,
|
from: segment.from,
|
||||||
to: segment.to,
|
to: segment.to,
|
||||||
} as const
|
}
|
||||||
let update: SegmentUtils['update'] | null = null
|
let update: SegmentUtils['update'] | null = null
|
||||||
if (type === TANGENTIAL_ARC_TO_SEGMENT) {
|
if (type === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
update = segmentUtils.tangentialArcTo.update
|
update = segmentUtils.tangentialArcTo.update
|
||||||
} else if (type === STRAIGHT_SEGMENT) {
|
} else if (type === STRAIGHT_SEGMENT) {
|
||||||
update = segmentUtils.straight.update
|
update = segmentUtils.straight.update
|
||||||
|
} else if (
|
||||||
|
type === CIRCLE_SEGMENT &&
|
||||||
|
'type' in segment &&
|
||||||
|
segment.type === 'Circle'
|
||||||
|
) {
|
||||||
|
update = segmentUtils.circle.update
|
||||||
|
input = {
|
||||||
|
type: 'arc-segment',
|
||||||
|
from: segment.from,
|
||||||
|
center: segment.center,
|
||||||
|
radius: segment.radius,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const callBack =
|
const callBack =
|
||||||
update &&
|
update &&
|
||||||
@ -1276,7 +1519,7 @@ export class SceneEntities {
|
|||||||
this._tearDownSketch(callDepth + 1, resolve, reject, { removeAxis })
|
this._tearDownSketch(callDepth + 1, resolve, reject, { removeAxis })
|
||||||
}, delay)
|
}, delay)
|
||||||
} else {
|
} else {
|
||||||
reject()
|
resolve(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sceneInfra.camControls.enableRotate = true
|
sceneInfra.camControls.enableRotate = true
|
||||||
@ -1306,11 +1549,10 @@ export class SceneEntities {
|
|||||||
mat.color.set(obj.userData.baseColor)
|
mat.color.set(obj.userData.baseColor)
|
||||||
mat.color.offsetHSL(0, 0, 0.5)
|
mat.color.offsetHSL(0, 0, 0.5)
|
||||||
}
|
}
|
||||||
const parent = getParentGroup(selected, [
|
const parent = getParentGroup(
|
||||||
STRAIGHT_SEGMENT,
|
selected,
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
SEGMENT_BODIES_PLUS_PROFILE_START
|
||||||
PROFILE_START,
|
)
|
||||||
])
|
|
||||||
if (parent?.userData?.pathToNode) {
|
if (parent?.userData?.pathToNode) {
|
||||||
const updatedAst = parse(recast(kclManager.ast))
|
const updatedAst = parse(recast(kclManager.ast))
|
||||||
if (trap(updatedAst)) return
|
if (trap(updatedAst)) return
|
||||||
@ -1334,11 +1576,11 @@ export class SceneEntities {
|
|||||||
}
|
}
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
const input = {
|
let input: SegmentInputs = {
|
||||||
type: 'straight-segment',
|
type: 'straight-segment',
|
||||||
from: parent.userData.from,
|
from: parent.userData.from,
|
||||||
to: parent.userData.to,
|
to: parent.userData.to,
|
||||||
} as const
|
}
|
||||||
const factor =
|
const factor =
|
||||||
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||||
? orthoFactor
|
? orthoFactor
|
||||||
@ -1349,6 +1591,12 @@ export class SceneEntities {
|
|||||||
update = segmentUtils.straight.update
|
update = segmentUtils.straight.update
|
||||||
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
update = segmentUtils.tangentialArcTo.update
|
update = segmentUtils.tangentialArcTo.update
|
||||||
|
input = {
|
||||||
|
type: 'arc-segment',
|
||||||
|
from: parent.userData.from,
|
||||||
|
radius: parent.userData.radius,
|
||||||
|
center: parent.userData.center,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
update &&
|
update &&
|
||||||
update({
|
update({
|
||||||
@ -1364,19 +1612,18 @@ export class SceneEntities {
|
|||||||
},
|
},
|
||||||
onMouseLeave: ({ selected, ...rest }: OnMouseEnterLeaveArgs) => {
|
onMouseLeave: ({ selected, ...rest }: OnMouseEnterLeaveArgs) => {
|
||||||
editorManager.setHighlightRange([[0, 0]])
|
editorManager.setHighlightRange([[0, 0]])
|
||||||
const parent = getParentGroup(selected, [
|
const parent = getParentGroup(
|
||||||
STRAIGHT_SEGMENT,
|
selected,
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
SEGMENT_BODIES_PLUS_PROFILE_START
|
||||||
PROFILE_START,
|
)
|
||||||
])
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
const input = {
|
let input: SegmentInputs = {
|
||||||
type: 'straight-segment',
|
type: 'straight-segment',
|
||||||
from: parent.userData.from,
|
from: parent.userData.from,
|
||||||
to: parent.userData.to,
|
to: parent.userData.to,
|
||||||
} as const
|
}
|
||||||
const factor =
|
const factor =
|
||||||
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||||
? orthoFactor
|
? orthoFactor
|
||||||
@ -1387,6 +1634,12 @@ export class SceneEntities {
|
|||||||
update = segmentUtils.straight.update
|
update = segmentUtils.straight.update
|
||||||
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
update = segmentUtils.tangentialArcTo.update
|
update = segmentUtils.tangentialArcTo.update
|
||||||
|
input = {
|
||||||
|
type: 'arc-segment',
|
||||||
|
from: parent.userData.from,
|
||||||
|
radius: parent.userData.radius,
|
||||||
|
center: parent.userData.center,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
update &&
|
update &&
|
||||||
update({
|
update({
|
||||||
@ -1557,7 +1810,7 @@ function prepareTruncatedMemoryAndAst(
|
|||||||
|
|
||||||
export function getParentGroup(
|
export function getParentGroup(
|
||||||
object: any,
|
object: any,
|
||||||
stopAt: string[] = [STRAIGHT_SEGMENT, TANGENTIAL_ARC_TO_SEGMENT]
|
stopAt: string[] = SEGMENT_BODIES
|
||||||
): Group | null {
|
): Group | null {
|
||||||
if (stopAt.includes(object?.userData?.type)) {
|
if (stopAt.includes(object?.userData?.type)) {
|
||||||
return object
|
return object
|
||||||
@ -1604,10 +1857,7 @@ function colorSegment(object: any, color: number) {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const straightSegmentBody = getParentGroup(object, [
|
const straightSegmentBody = getParentGroup(object, SEGMENT_BODIES)
|
||||||
STRAIGHT_SEGMENT,
|
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
|
||||||
])
|
|
||||||
if (straightSegmentBody) {
|
if (straightSegmentBody) {
|
||||||
straightSegmentBody.traverse((child) => {
|
straightSegmentBody.traverse((child) => {
|
||||||
if (child instanceof Mesh && !child.userData.ignoreColorChange) {
|
if (child instanceof Mesh && !child.userData.ignoreColorChange) {
|
||||||
|
@ -92,6 +92,8 @@ interface OnMoveCallbackArgs {
|
|||||||
// This singleton class is responsible for all of the under the hood setup for the client side scene.
|
// This singleton class is responsible for all of the under the hood setup for the client side scene.
|
||||||
// That is the cameras and switching between them, raycasters for click mouse events and their abstractions (onClick etc), setting up controls.
|
// That is the cameras and switching between them, raycasters for click mouse events and their abstractions (onClick etc), setting up controls.
|
||||||
// Anything that added the the scene for the user to interact with is probably in SceneEntities.ts
|
// Anything that added the the scene for the user to interact with is probably in SceneEntities.ts
|
||||||
|
|
||||||
|
type Voidish = void | Promise<void>
|
||||||
export class SceneInfra {
|
export class SceneInfra {
|
||||||
static instance: SceneInfra
|
static instance: SceneInfra
|
||||||
scene: Scene
|
scene: Scene
|
||||||
@ -107,21 +109,21 @@ export class SceneInfra {
|
|||||||
_theme: Themes = Themes.System
|
_theme: Themes = Themes.System
|
||||||
extraSegmentTexture: Texture
|
extraSegmentTexture: Texture
|
||||||
lastMouseState: MouseState = { type: 'idle' }
|
lastMouseState: MouseState = { type: 'idle' }
|
||||||
onDragStartCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragStartCallback: (arg: OnDragCallbackArgs) => Voidish = () => {}
|
||||||
onDragEndCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragEndCallback: (arg: OnDragCallbackArgs) => Voidish = () => {}
|
||||||
onDragCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragCallback: (arg: OnDragCallbackArgs) => Voidish = () => {}
|
||||||
onMoveCallback: (arg: OnMoveCallbackArgs) => void = () => {}
|
onMoveCallback: (arg: OnMoveCallbackArgs) => Voidish = () => {}
|
||||||
onClickCallback: (arg: OnClickCallbackArgs) => void = () => {}
|
onClickCallback: (arg: OnClickCallbackArgs) => Voidish = () => {}
|
||||||
onMouseEnter: (arg: OnMouseEnterLeaveArgs) => void = () => {}
|
onMouseEnter: (arg: OnMouseEnterLeaveArgs) => Voidish = () => {}
|
||||||
onMouseLeave: (arg: OnMouseEnterLeaveArgs) => void = () => {}
|
onMouseLeave: (arg: OnMouseEnterLeaveArgs) => Voidish = () => {}
|
||||||
setCallbacks = (callbacks: {
|
setCallbacks = (callbacks: {
|
||||||
onDragStart?: (arg: OnDragCallbackArgs) => void
|
onDragStart?: (arg: OnDragCallbackArgs) => Voidish
|
||||||
onDragEnd?: (arg: OnDragCallbackArgs) => void
|
onDragEnd?: (arg: OnDragCallbackArgs) => Voidish
|
||||||
onDrag?: (arg: OnDragCallbackArgs) => void
|
onDrag?: (arg: OnDragCallbackArgs) => Voidish
|
||||||
onMove?: (arg: OnMoveCallbackArgs) => void
|
onMove?: (arg: OnMoveCallbackArgs) => Voidish
|
||||||
onClick?: (arg: OnClickCallbackArgs) => void
|
onClick?: (arg: OnClickCallbackArgs) => Voidish
|
||||||
onMouseEnter?: (arg: OnMouseEnterLeaveArgs) => void
|
onMouseEnter?: (arg: OnMouseEnterLeaveArgs) => Voidish
|
||||||
onMouseLeave?: (arg: OnMouseEnterLeaveArgs) => void
|
onMouseLeave?: (arg: OnMouseEnterLeaveArgs) => Voidish
|
||||||
}) => {
|
}) => {
|
||||||
this.onDragStartCallback = callbacks.onDragStart || this.onDragStartCallback
|
this.onDragStartCallback = callbacks.onDragStart || this.onDragStartCallback
|
||||||
this.onDragEndCallback = callbacks.onDragEnd || this.onDragEndCallback
|
this.onDragEndCallback = callbacks.onDragEnd || this.onDragEndCallback
|
||||||
@ -389,7 +391,7 @@ export class SceneInfra {
|
|||||||
intersection: planeIntersects[0],
|
intersection: planeIntersects[0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMouseMove = (mouseEvent: MouseEvent) => {
|
onMouseMove = async (mouseEvent: MouseEvent) => {
|
||||||
this.currentMouseVector.x = (mouseEvent.clientX / window.innerWidth) * 2 - 1
|
this.currentMouseVector.x = (mouseEvent.clientX / window.innerWidth) * 2 - 1
|
||||||
this.currentMouseVector.y =
|
this.currentMouseVector.y =
|
||||||
-(mouseEvent.clientY / window.innerHeight) * 2 + 1
|
-(mouseEvent.clientY / window.innerHeight) * 2 + 1
|
||||||
@ -414,7 +416,7 @@ export class SceneInfra {
|
|||||||
planeIntersectPoint.twoD &&
|
planeIntersectPoint.twoD &&
|
||||||
planeIntersectPoint.threeD
|
planeIntersectPoint.threeD
|
||||||
) {
|
) {
|
||||||
this.onDragCallback({
|
await this.onDragCallback({
|
||||||
mouseEvent,
|
mouseEvent,
|
||||||
intersectionPoint: {
|
intersectionPoint: {
|
||||||
twoD: planeIntersectPoint.twoD,
|
twoD: planeIntersectPoint.twoD,
|
||||||
@ -433,7 +435,7 @@ export class SceneInfra {
|
|||||||
planeIntersectPoint.twoD &&
|
planeIntersectPoint.twoD &&
|
||||||
planeIntersectPoint.threeD
|
planeIntersectPoint.threeD
|
||||||
) {
|
) {
|
||||||
this.onMoveCallback({
|
await this.onMoveCallback({
|
||||||
mouseEvent,
|
mouseEvent,
|
||||||
intersectionPoint: {
|
intersectionPoint: {
|
||||||
twoD: planeIntersectPoint.twoD,
|
twoD: planeIntersectPoint.twoD,
|
||||||
@ -448,12 +450,12 @@ export class SceneInfra {
|
|||||||
if (this.hoveredObject !== firstIntersectObject) {
|
if (this.hoveredObject !== firstIntersectObject) {
|
||||||
const hoveredObj = this.hoveredObject
|
const hoveredObj = this.hoveredObject
|
||||||
this.hoveredObject = null
|
this.hoveredObject = null
|
||||||
this.onMouseLeave({
|
await this.onMouseLeave({
|
||||||
selected: hoveredObj,
|
selected: hoveredObj,
|
||||||
mouseEvent: mouseEvent,
|
mouseEvent: mouseEvent,
|
||||||
})
|
})
|
||||||
this.hoveredObject = firstIntersectObject
|
this.hoveredObject = firstIntersectObject
|
||||||
this.onMouseEnter({
|
await this.onMouseEnter({
|
||||||
selected: this.hoveredObject,
|
selected: this.hoveredObject,
|
||||||
dragSelected: this.selected?.object,
|
dragSelected: this.selected?.object,
|
||||||
mouseEvent: mouseEvent,
|
mouseEvent: mouseEvent,
|
||||||
@ -468,7 +470,7 @@ export class SceneInfra {
|
|||||||
if (this.hoveredObject) {
|
if (this.hoveredObject) {
|
||||||
const hoveredObj = this.hoveredObject
|
const hoveredObj = this.hoveredObject
|
||||||
this.hoveredObject = null
|
this.hoveredObject = null
|
||||||
this.onMouseLeave({
|
await this.onMouseLeave({
|
||||||
selected: hoveredObj,
|
selected: hoveredObj,
|
||||||
dragSelected: this.selected?.object,
|
dragSelected: this.selected?.object,
|
||||||
mouseEvent: mouseEvent,
|
mouseEvent: mouseEvent,
|
||||||
@ -555,7 +557,7 @@ export class SceneInfra {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseUp = (mouseEvent: MouseEvent) => {
|
onMouseUp = async (mouseEvent: MouseEvent) => {
|
||||||
this.currentMouseVector.x = (mouseEvent.clientX / window.innerWidth) * 2 - 1
|
this.currentMouseVector.x = (mouseEvent.clientX / window.innerWidth) * 2 - 1
|
||||||
this.currentMouseVector.y =
|
this.currentMouseVector.y =
|
||||||
-(mouseEvent.clientY / window.innerHeight) * 2 + 1
|
-(mouseEvent.clientY / window.innerHeight) * 2 + 1
|
||||||
@ -565,7 +567,7 @@ export class SceneInfra {
|
|||||||
if (this.selected) {
|
if (this.selected) {
|
||||||
if (this.selected.hasBeenDragged) {
|
if (this.selected.hasBeenDragged) {
|
||||||
// TODO do the types properly here
|
// TODO do the types properly here
|
||||||
this.onDragEndCallback({
|
await this.onDragEndCallback({
|
||||||
intersectionPoint: {
|
intersectionPoint: {
|
||||||
twoD: planeIntersectPoint?.twoD as any,
|
twoD: planeIntersectPoint?.twoD as any,
|
||||||
threeD: planeIntersectPoint?.threeD as any,
|
threeD: planeIntersectPoint?.threeD as any,
|
||||||
@ -586,7 +588,7 @@ export class SceneInfra {
|
|||||||
}
|
}
|
||||||
} else if (planeIntersectPoint?.twoD && planeIntersectPoint?.threeD) {
|
} else if (planeIntersectPoint?.twoD && planeIntersectPoint?.threeD) {
|
||||||
// fire onClick event as there was no drags
|
// fire onClick event as there was no drags
|
||||||
this.onClickCallback({
|
await this.onClickCallback({
|
||||||
mouseEvent,
|
mouseEvent,
|
||||||
intersectionPoint: {
|
intersectionPoint: {
|
||||||
twoD: planeIntersectPoint.twoD,
|
twoD: planeIntersectPoint.twoD,
|
||||||
@ -596,17 +598,17 @@ export class SceneInfra {
|
|||||||
selected: this.selected.object,
|
selected: this.selected.object,
|
||||||
})
|
})
|
||||||
} else if (planeIntersectPoint) {
|
} else if (planeIntersectPoint) {
|
||||||
this.onClickCallback({
|
await this.onClickCallback({
|
||||||
mouseEvent,
|
mouseEvent,
|
||||||
intersects,
|
intersects,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.onClickCallback({ mouseEvent, intersects })
|
await this.onClickCallback({ mouseEvent, intersects })
|
||||||
}
|
}
|
||||||
// Clear the selected state whether it was dragged or not
|
// Clear the selected state whether it was dragged or not
|
||||||
this.selected = null
|
this.selected = null
|
||||||
} else if (planeIntersectPoint?.twoD && planeIntersectPoint?.threeD) {
|
} else if (planeIntersectPoint?.twoD && planeIntersectPoint?.threeD) {
|
||||||
this.onClickCallback({
|
await this.onClickCallback({
|
||||||
mouseEvent,
|
mouseEvent,
|
||||||
intersectionPoint: {
|
intersectionPoint: {
|
||||||
twoD: planeIntersectPoint.twoD,
|
twoD: planeIntersectPoint.twoD,
|
||||||
@ -615,7 +617,7 @@ export class SceneInfra {
|
|||||||
intersects,
|
intersects,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.onClickCallback({ mouseEvent, intersects })
|
await this.onClickCallback({ mouseEvent, intersects })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateOtherSelectionColors = (otherSelections: Axis[]) => {
|
updateOtherSelectionColors = (otherSelections: Axis[]) => {
|
||||||
|
@ -24,6 +24,10 @@ import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js
|
|||||||
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
||||||
import { PathToNode, SketchGroup, getTangentialArcToInfo } from 'lang/wasm'
|
import { PathToNode, SketchGroup, getTangentialArcToInfo } from 'lang/wasm'
|
||||||
import {
|
import {
|
||||||
|
CIRCLE_CENTER_HANDLE,
|
||||||
|
CIRCLE_SEGMENT,
|
||||||
|
CIRCLE_SEGMENT_BODY,
|
||||||
|
CIRCLE_SEGMENT_DASH,
|
||||||
EXTRA_SEGMENT_HANDLE,
|
EXTRA_SEGMENT_HANDLE,
|
||||||
EXTRA_SEGMENT_OFFSET_PX,
|
EXTRA_SEGMENT_OFFSET_PX,
|
||||||
HIDE_HOVER_SEGMENT_LENGTH,
|
HIDE_HOVER_SEGMENT_LENGTH,
|
||||||
@ -477,6 +481,169 @@ class TangentialArcToSegment implements SegmentUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CircleSegment implements SegmentUtils {
|
||||||
|
init: SegmentUtils['init'] = ({
|
||||||
|
prevSegment,
|
||||||
|
input,
|
||||||
|
id,
|
||||||
|
pathToNode,
|
||||||
|
isDraftSegment,
|
||||||
|
scale = 1,
|
||||||
|
theme,
|
||||||
|
isSelected,
|
||||||
|
sceneInfra,
|
||||||
|
}) => {
|
||||||
|
if (input.type !== 'arc-segment') {
|
||||||
|
return new Error('Invalid segment type')
|
||||||
|
}
|
||||||
|
const { from, center, radius } = input
|
||||||
|
const baseColor = getThemeColorForThreeJs(theme)
|
||||||
|
const color = isSelected ? 0x0000ff : baseColor
|
||||||
|
|
||||||
|
const group = new Group()
|
||||||
|
const geometry = createArcGeometry({
|
||||||
|
center,
|
||||||
|
radius,
|
||||||
|
startAngle: 0,
|
||||||
|
endAngle: Math.PI * 2,
|
||||||
|
ccw: true,
|
||||||
|
isDashed: isDraftSegment,
|
||||||
|
scale,
|
||||||
|
})
|
||||||
|
const mat = new MeshBasicMaterial({ color })
|
||||||
|
const arcMesh = new Mesh(geometry, mat)
|
||||||
|
const meshType = isDraftSegment ? CIRCLE_SEGMENT_DASH : CIRCLE_SEGMENT_BODY
|
||||||
|
const arrowGroup = createArrowhead(scale, theme, color)
|
||||||
|
const circleCenterGroup = createCircleCenterHandle(scale, theme, color)
|
||||||
|
|
||||||
|
arcMesh.userData.type = meshType
|
||||||
|
arcMesh.name = meshType
|
||||||
|
group.userData = {
|
||||||
|
type: CIRCLE_SEGMENT,
|
||||||
|
id,
|
||||||
|
from,
|
||||||
|
radius,
|
||||||
|
center,
|
||||||
|
ccw: true,
|
||||||
|
prevSegment,
|
||||||
|
pathToNode,
|
||||||
|
isSelected,
|
||||||
|
baseColor,
|
||||||
|
}
|
||||||
|
group.name = CIRCLE_SEGMENT
|
||||||
|
|
||||||
|
group.add(arcMesh, arrowGroup, circleCenterGroup)
|
||||||
|
const updateOverlaysCallback = this.update({
|
||||||
|
prevSegment,
|
||||||
|
input,
|
||||||
|
group,
|
||||||
|
scale,
|
||||||
|
sceneInfra,
|
||||||
|
})
|
||||||
|
if (err(updateOverlaysCallback)) return updateOverlaysCallback
|
||||||
|
|
||||||
|
return {
|
||||||
|
group,
|
||||||
|
updateOverlaysCallback,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update: SegmentUtils['update'] = ({
|
||||||
|
prevSegment,
|
||||||
|
input,
|
||||||
|
group,
|
||||||
|
scale = 1,
|
||||||
|
sceneInfra,
|
||||||
|
}) => {
|
||||||
|
if (input.type !== 'arc-segment') {
|
||||||
|
return new Error('Invalid segment type')
|
||||||
|
}
|
||||||
|
const { from, center, radius } = input
|
||||||
|
group.userData.from = from
|
||||||
|
// group.userData.to = to
|
||||||
|
group.userData.center = center
|
||||||
|
group.userData.radius = radius
|
||||||
|
group.userData.prevSegment = prevSegment
|
||||||
|
const arrowGroup = group.getObjectByName(ARROWHEAD) as Group
|
||||||
|
const circleCenterHandle = group.getObjectByName(
|
||||||
|
CIRCLE_CENTER_HANDLE
|
||||||
|
) as Group
|
||||||
|
|
||||||
|
const pxLength = (2 * radius * Math.PI) / scale
|
||||||
|
const shouldHideIdle = pxLength < HIDE_SEGMENT_LENGTH
|
||||||
|
const shouldHideHover = pxLength < HIDE_HOVER_SEGMENT_LENGTH
|
||||||
|
|
||||||
|
const hoveredParent =
|
||||||
|
sceneInfra.hoveredObject &&
|
||||||
|
getParentGroup(sceneInfra.hoveredObject, [CIRCLE_SEGMENT])
|
||||||
|
let isHandlesVisible = !shouldHideIdle
|
||||||
|
if (hoveredParent && hoveredParent?.uuid === group?.uuid) {
|
||||||
|
isHandlesVisible = !shouldHideHover
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arrowGroup) {
|
||||||
|
arrowGroup.position.set(
|
||||||
|
center[0] + Math.cos(Math.PI / 4) * radius,
|
||||||
|
center[1] + Math.sin(Math.PI / 4) * radius,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
|
||||||
|
const arrowheadAngle = Math.PI / 4
|
||||||
|
arrowGroup.quaternion.setFromUnitVectors(
|
||||||
|
new Vector3(0, 1, 0),
|
||||||
|
new Vector3(Math.cos(arrowheadAngle), Math.sin(arrowheadAngle), 0)
|
||||||
|
)
|
||||||
|
arrowGroup.scale.set(scale, scale, scale)
|
||||||
|
arrowGroup.visible = isHandlesVisible
|
||||||
|
}
|
||||||
|
|
||||||
|
if (circleCenterHandle) {
|
||||||
|
circleCenterHandle.position.set(center[0], center[1], 0)
|
||||||
|
circleCenterHandle.scale.set(scale, scale, scale)
|
||||||
|
circleCenterHandle.visible = isHandlesVisible
|
||||||
|
}
|
||||||
|
|
||||||
|
const circleSegmentBody = group.children.find(
|
||||||
|
(child) => child.userData.type === CIRCLE_SEGMENT_BODY
|
||||||
|
) as Mesh
|
||||||
|
|
||||||
|
if (circleSegmentBody) {
|
||||||
|
const newGeo = createArcGeometry({
|
||||||
|
radius,
|
||||||
|
center,
|
||||||
|
startAngle: 0,
|
||||||
|
endAngle: Math.PI * 2,
|
||||||
|
ccw: true,
|
||||||
|
scale,
|
||||||
|
})
|
||||||
|
circleSegmentBody.geometry = newGeo
|
||||||
|
}
|
||||||
|
const circleSegmentBodyDashed = group.getObjectByName(CIRCLE_SEGMENT_DASH)
|
||||||
|
if (circleSegmentBodyDashed instanceof Mesh) {
|
||||||
|
// consider throttling the whole updateTangentialArcToSegment
|
||||||
|
// if there are more perf considerations going forward
|
||||||
|
circleSegmentBodyDashed.geometry = createArcGeometry({
|
||||||
|
center,
|
||||||
|
radius,
|
||||||
|
ccw: true,
|
||||||
|
// make the start end where the handle is
|
||||||
|
startAngle: Math.PI * 0.25,
|
||||||
|
endAngle: Math.PI * 2.25,
|
||||||
|
isDashed: true,
|
||||||
|
scale,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return () =>
|
||||||
|
sceneInfra.updateOverlayDetails({
|
||||||
|
arrowGroup,
|
||||||
|
group,
|
||||||
|
isHandlesVisible,
|
||||||
|
from: from,
|
||||||
|
to: [center[0], center[1]],
|
||||||
|
angle: Math.PI / 4,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function createProfileStartHandle({
|
export function createProfileStartHandle({
|
||||||
from,
|
from,
|
||||||
id,
|
id,
|
||||||
@ -535,6 +702,28 @@ function createArrowhead(scale = 1, theme: Themes, color?: number): Group {
|
|||||||
arrowGroup.scale.set(scale, scale, scale)
|
arrowGroup.scale.set(scale, scale, scale)
|
||||||
return arrowGroup
|
return arrowGroup
|
||||||
}
|
}
|
||||||
|
function createCircleCenterHandle(
|
||||||
|
scale = 1,
|
||||||
|
theme: Themes,
|
||||||
|
color?: number
|
||||||
|
): Group {
|
||||||
|
const circleCenterGroup = new Group()
|
||||||
|
|
||||||
|
const geometry = new BoxGeometry(12, 12, 12) // in pixels scaled later
|
||||||
|
const baseColor = getThemeColorForThreeJs(theme)
|
||||||
|
const body = new MeshBasicMaterial({ color })
|
||||||
|
const mesh = new Mesh(geometry, body)
|
||||||
|
|
||||||
|
circleCenterGroup.add(mesh)
|
||||||
|
|
||||||
|
circleCenterGroup.userData = {
|
||||||
|
type: CIRCLE_CENTER_HANDLE,
|
||||||
|
baseColor,
|
||||||
|
}
|
||||||
|
circleCenterGroup.name = CIRCLE_CENTER_HANDLE
|
||||||
|
circleCenterGroup.scale.set(scale, scale, scale)
|
||||||
|
return circleCenterGroup
|
||||||
|
}
|
||||||
|
|
||||||
function createExtraSegmentHandle(
|
function createExtraSegmentHandle(
|
||||||
scale: number,
|
scale: number,
|
||||||
@ -788,4 +977,5 @@ export function dashedStraight(
|
|||||||
export const segmentUtils = {
|
export const segmentUtils = {
|
||||||
straight: new StraightSegment(),
|
straight: new StraightSegment(),
|
||||||
tangentialArcTo: new TangentialArcToSegment(),
|
tangentialArcTo: new TangentialArcToSegment(),
|
||||||
|
circle: new CircleSegment(),
|
||||||
} as const
|
} as const
|
||||||
|
@ -33,11 +33,15 @@ function CommandBarBasicInput({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form id="arg-form" onSubmit={handleSubmit}>
|
<form id="arg-form" onSubmit={handleSubmit}>
|
||||||
<label className="flex items-center mx-4 my-4">
|
<label
|
||||||
|
data-testid="cmd-bar-arg-name"
|
||||||
|
className="flex items-center mx-4 my-4"
|
||||||
|
>
|
||||||
<span className="capitalize px-2 py-1 rounded-l bg-chalkboard-100 dark:bg-chalkboard-80 text-chalkboard-10 border-b border-b-chalkboard-100 dark:border-b-chalkboard-80">
|
<span className="capitalize px-2 py-1 rounded-l bg-chalkboard-100 dark:bg-chalkboard-80 text-chalkboard-10 border-b border-b-chalkboard-100 dark:border-b-chalkboard-80">
|
||||||
{arg.name}
|
{arg.name}
|
||||||
</span>
|
</span>
|
||||||
<input
|
<input
|
||||||
|
data-testid="cmd-bar-arg-value"
|
||||||
id="arg-form"
|
id="arg-form"
|
||||||
name={arg.inputType}
|
name={arg.inputType}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
@ -74,7 +74,9 @@ function CommandBarHeader({ children }: React.PropsWithChildren<{}>) {
|
|||||||
selectedCommand.icon && (
|
selectedCommand.icon && (
|
||||||
<CustomIcon name={selectedCommand.icon} className="w-5 h-5" />
|
<CustomIcon name={selectedCommand.icon} className="w-5 h-5" />
|
||||||
)}
|
)}
|
||||||
{selectedCommand.displayName || selectedCommand.name}
|
<span data-testid="command-name">
|
||||||
|
{selectedCommand.displayName || selectedCommand.name}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
{Object.entries(selectedCommand?.args || {})
|
{Object.entries(selectedCommand?.args || {})
|
||||||
.filter(([_, argConfig]) =>
|
.filter(([_, argConfig]) =>
|
||||||
@ -92,6 +94,10 @@ function CommandBarHeader({ children }: React.PropsWithChildren<{}>) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
data-testid="cmd-bar-input-tab"
|
||||||
|
data-is-current-arg={
|
||||||
|
argName === currentArgument?.name ? 'true' : 'false'
|
||||||
|
}
|
||||||
disabled={!isReviewing && currentArgument?.name === argName}
|
disabled={!isReviewing && currentArgument?.name === argName}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
commandBarSend({
|
commandBarSend({
|
||||||
@ -110,29 +116,34 @@ function CommandBarHeader({ children }: React.PropsWithChildren<{}>) {
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
data-testid={`arg-name-${argName.toLowerCase()}`}
|
data-testid={`arg-name-${argName.toLowerCase()}`}
|
||||||
|
data-test-name="arg-name"
|
||||||
className="capitalize"
|
className="capitalize"
|
||||||
>
|
>
|
||||||
{argName}
|
{argName}
|
||||||
</span>
|
</span>
|
||||||
<span className="sr-only">: </span>
|
<span className="sr-only">: </span>
|
||||||
{argValue ? (
|
<span data-testid="header-arg-value">
|
||||||
arg.inputType === 'selection' ? (
|
{argValue ? (
|
||||||
getSelectionTypeDisplayText(argValue as Selections)
|
arg.inputType === 'selection' ? (
|
||||||
) : arg.inputType === 'kcl' ? (
|
getSelectionTypeDisplayText(argValue as Selections)
|
||||||
roundOff(
|
) : arg.inputType === 'kcl' ? (
|
||||||
Number((argValue as KclCommandValue).valueCalculated),
|
roundOff(
|
||||||
4
|
Number(
|
||||||
)
|
(argValue as KclCommandValue).valueCalculated
|
||||||
) : typeof argValue === 'object' ? (
|
),
|
||||||
arg.valueSummary ? (
|
4
|
||||||
arg.valueSummary(argValue)
|
)
|
||||||
|
) : typeof argValue === 'object' ? (
|
||||||
|
arg.valueSummary ? (
|
||||||
|
arg.valueSummary(argValue)
|
||||||
|
) : (
|
||||||
|
JSON.stringify(argValue)
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
JSON.stringify(argValue)
|
<em>{argValue}</em>
|
||||||
)
|
)
|
||||||
) : (
|
) : null}
|
||||||
<em>{argValue}</em>
|
</span>
|
||||||
)
|
|
||||||
) : null}
|
|
||||||
{showShortcuts && (
|
{showShortcuts && (
|
||||||
<small className="absolute -top-[1px] right-full translate-x-1/2 px-0.5 rounded-sm bg-chalkboard-80 text-chalkboard-10 dark:bg-primary dark:text-chalkboard-100">
|
<small className="absolute -top-[1px] right-full translate-x-1/2 px-0.5 rounded-sm bg-chalkboard-80 text-chalkboard-10 dark:bg-primary dark:text-chalkboard-100">
|
||||||
<span className="sr-only">Hotkey: </span>
|
<span className="sr-only">Hotkey: </span>
|
||||||
|
@ -139,10 +139,17 @@ function CommandBarKclInput({
|
|||||||
return (
|
return (
|
||||||
<form id="arg-form" onSubmit={handleSubmit} data-can-submit={canSubmit}>
|
<form id="arg-form" onSubmit={handleSubmit} data-can-submit={canSubmit}>
|
||||||
<label className="flex gap-4 items-center mx-4 my-4 border-solid border-b border-chalkboard-50">
|
<label className="flex gap-4 items-center mx-4 my-4 border-solid border-b border-chalkboard-50">
|
||||||
<span className="capitalize text-chalkboard-80 dark:text-chalkboard-20">
|
<span
|
||||||
|
data-testid="cmd-bar-arg-name"
|
||||||
|
className="capitalize text-chalkboard-80 dark:text-chalkboard-20"
|
||||||
|
>
|
||||||
{arg.name}
|
{arg.name}
|
||||||
</span>
|
</span>
|
||||||
<div ref={editorRef} className={styles.editor} />
|
<div
|
||||||
|
data-testid="cmd-bar-arg-value"
|
||||||
|
ref={editorRef}
|
||||||
|
className={styles.editor}
|
||||||
|
/>
|
||||||
<CustomIcon
|
<CustomIcon
|
||||||
name="equal"
|
name="equal"
|
||||||
className="w-5 h-5 text-chalkboard-70 dark:text-chalkboard-40"
|
className="w-5 h-5 text-chalkboard-70 dark:text-chalkboard-40"
|
||||||
|
@ -36,10 +36,14 @@ function CommandBarTextareaInput({
|
|||||||
return (
|
return (
|
||||||
<form id="arg-form" onSubmit={handleSubmit} ref={formRef}>
|
<form id="arg-form" onSubmit={handleSubmit} ref={formRef}>
|
||||||
<label className="flex items-start rounded mx-4 my-4 border border-chalkboard-100 dark:border-chalkboard-80">
|
<label className="flex items-start rounded mx-4 my-4 border border-chalkboard-100 dark:border-chalkboard-80">
|
||||||
<span className="capitalize px-2 py-1 rounded-br bg-chalkboard-100 dark:bg-chalkboard-80 text-chalkboard-10 border-b border-b-chalkboard-100 dark:border-b-chalkboard-80">
|
<span
|
||||||
|
data-testid="cmd-bar-arg-name"
|
||||||
|
className="capitalize px-2 py-1 rounded-br bg-chalkboard-100 dark:bg-chalkboard-80 text-chalkboard-10 border-b border-b-chalkboard-100 dark:border-b-chalkboard-80"
|
||||||
|
>
|
||||||
{arg.name}
|
{arg.name}
|
||||||
</span>
|
</span>
|
||||||
<textarea
|
<textarea
|
||||||
|
data-testid="cmd-bar-arg-value"
|
||||||
id="arg-form"
|
id="arg-form"
|
||||||
name={arg.inputType}
|
name={arg.inputType}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
@ -41,7 +41,7 @@ import {
|
|||||||
canSweepSelection,
|
canSweepSelection,
|
||||||
handleSelectionBatch,
|
handleSelectionBatch,
|
||||||
isSelectionLastLine,
|
isSelectionLastLine,
|
||||||
isRangeInbetweenCharacters,
|
isRangeBetweenCharacters,
|
||||||
isSketchPipe,
|
isSketchPipe,
|
||||||
updateSelections,
|
updateSelections,
|
||||||
} from 'lib/selections'
|
} from 'lib/selections'
|
||||||
@ -50,8 +50,7 @@ import { applyConstraintAbsDistance } from './Toolbar/SetAbsDistance'
|
|||||||
import useStateMachineCommands from 'hooks/useStateMachineCommands'
|
import useStateMachineCommands from 'hooks/useStateMachineCommands'
|
||||||
import { modelingMachineCommandConfig } from 'lib/commandBarConfigs/modelingCommandConfig'
|
import { modelingMachineCommandConfig } from 'lib/commandBarConfigs/modelingCommandConfig'
|
||||||
import {
|
import {
|
||||||
STRAIGHT_SEGMENT,
|
SEGMENT_BODIES,
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
|
||||||
getParentGroup,
|
getParentGroup,
|
||||||
getSketchOrientationDetails,
|
getSketchOrientationDetails,
|
||||||
} from 'clientSideScene/sceneEntities'
|
} from 'clientSideScene/sceneEntities'
|
||||||
@ -168,10 +167,7 @@ export const ModelingMachineProvider = ({
|
|||||||
if (event.type !== 'Set mouse state') return {}
|
if (event.type !== 'Set mouse state') return {}
|
||||||
const nextSegmentHoverMap = () => {
|
const nextSegmentHoverMap = () => {
|
||||||
if (event.data.type === 'isHovering') {
|
if (event.data.type === 'isHovering') {
|
||||||
const parent = getParentGroup(event.data.on, [
|
const parent = getParentGroup(event.data.on, SEGMENT_BODIES)
|
||||||
STRAIGHT_SEGMENT,
|
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
|
||||||
])
|
|
||||||
const pathToNode = parent?.userData?.pathToNode
|
const pathToNode = parent?.userData?.pathToNode
|
||||||
const pathToNodeString = JSON.stringify(pathToNode)
|
const pathToNodeString = JSON.stringify(pathToNode)
|
||||||
if (!parent || !pathToNode) return context.segmentHoverMap
|
if (!parent || !pathToNode) return context.segmentHoverMap
|
||||||
@ -187,10 +183,10 @@ export const ModelingMachineProvider = ({
|
|||||||
event.data.type === 'idle' &&
|
event.data.type === 'idle' &&
|
||||||
context.mouseState.type === 'isHovering'
|
context.mouseState.type === 'isHovering'
|
||||||
) {
|
) {
|
||||||
const mouseOnParent = getParentGroup(context.mouseState.on, [
|
const mouseOnParent = getParentGroup(
|
||||||
STRAIGHT_SEGMENT,
|
context.mouseState.on,
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
SEGMENT_BODIES
|
||||||
])
|
)
|
||||||
if (!mouseOnParent || !mouseOnParent?.userData?.pathToNode)
|
if (!mouseOnParent || !mouseOnParent?.userData?.pathToNode)
|
||||||
return context.segmentHoverMap
|
return context.segmentHoverMap
|
||||||
const pathToNodeString = JSON.stringify(
|
const pathToNodeString = JSON.stringify(
|
||||||
@ -204,8 +200,8 @@ export const ModelingMachineProvider = ({
|
|||||||
pathToNodeString,
|
pathToNodeString,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
// overlay timeout
|
// overlay timeout is 1s
|
||||||
}, 800) as unknown as number
|
}, 1000) as unknown as number
|
||||||
return {
|
return {
|
||||||
...context.segmentHoverMap,
|
...context.segmentHoverMap,
|
||||||
[pathToNodeString]: timeoutId,
|
[pathToNodeString]: timeoutId,
|
||||||
@ -495,43 +491,21 @@ export const ModelingMachineProvider = ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
guards: {
|
guards: {
|
||||||
'has valid extrude selection': ({ context: { selectionRanges } }) => {
|
'has valid sweep selection': ({ context: { selectionRanges } }) => {
|
||||||
// A user can begin extruding if they either have 1+ faces selected or nothing selected
|
// A user can begin extruding if they either have 1+ faces selected or nothing selected
|
||||||
// TODO: I believe this guard only allows for extruding a single face at a time
|
// TODO: I believe this guard only allows for extruding a single face at a time
|
||||||
const isPipe = isSketchPipe(selectionRanges)
|
const hasNoSelection =
|
||||||
|
|
||||||
if (
|
|
||||||
selectionRanges.codeBasedSelections.length === 0 ||
|
selectionRanges.codeBasedSelections.length === 0 ||
|
||||||
isRangeInbetweenCharacters(selectionRanges) ||
|
isRangeBetweenCharacters(selectionRanges) ||
|
||||||
isSelectionLastLine(selectionRanges, codeManager.code)
|
isSelectionLastLine(selectionRanges, codeManager.code)
|
||||||
) {
|
|
||||||
|
if (hasNoSelection) {
|
||||||
// they have no selection, we should enable the button
|
// they have no selection, we should enable the button
|
||||||
// so they can select the face through the cmdbar
|
// so they can select the face through the cmdbar
|
||||||
// BUT only if there's extrudable geometry
|
// BUT only if there's extrudable geometry
|
||||||
if (doesSceneHaveSweepableSketch(kclManager.ast)) return true
|
return doesSceneHaveSweepableSketch(kclManager.ast)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
if (!isPipe) return false
|
if (!isSketchPipe(selectionRanges)) return false
|
||||||
|
|
||||||
return canSweepSelection(selectionRanges)
|
|
||||||
},
|
|
||||||
'has valid revolve selection': ({ context: { selectionRanges } }) => {
|
|
||||||
// A user can begin extruding if they either have 1+ faces selected or nothing selected
|
|
||||||
// TODO: I believe this guard only allows for extruding a single face at a time
|
|
||||||
const isPipe = isSketchPipe(selectionRanges)
|
|
||||||
|
|
||||||
if (
|
|
||||||
selectionRanges.codeBasedSelections.length === 0 ||
|
|
||||||
isRangeInbetweenCharacters(selectionRanges) ||
|
|
||||||
isSelectionLastLine(selectionRanges, codeManager.code)
|
|
||||||
) {
|
|
||||||
// they have no selection, we should enable the button
|
|
||||||
// so they can select the face through the cmdbar
|
|
||||||
// BUT only if there's extrudable geometry
|
|
||||||
if (doesSceneHaveSweepableSketch(kclManager.ast)) return true
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (!isPipe) return false
|
|
||||||
|
|
||||||
return canSweepSelection(selectionRanges)
|
return canSweepSelection(selectionRanges)
|
||||||
},
|
},
|
||||||
|
@ -24,8 +24,9 @@ export type ToolTip =
|
|||||||
| 'yLineTo'
|
| 'yLineTo'
|
||||||
| 'angledLineThatIntersects'
|
| 'angledLineThatIntersects'
|
||||||
| 'tangentialArcTo'
|
| 'tangentialArcTo'
|
||||||
|
| 'circle'
|
||||||
|
|
||||||
export const toolTips = [
|
export const toolTips: Array<ToolTip> = [
|
||||||
'line',
|
'line',
|
||||||
'lineTo',
|
'lineTo',
|
||||||
'angledLine',
|
'angledLine',
|
||||||
|
@ -903,6 +903,7 @@ export function doesSceneHaveSweepableSketch(ast: Program) {
|
|||||||
let hasStartProfileAt = false
|
let hasStartProfileAt = false
|
||||||
let hasStartSketchOn = false
|
let hasStartSketchOn = false
|
||||||
let hasClose = false
|
let hasClose = false
|
||||||
|
let hasCircle = false
|
||||||
for (const pipe of node.init.body) {
|
for (const pipe of node.init.body) {
|
||||||
if (
|
if (
|
||||||
pipe.type === 'CallExpression' &&
|
pipe.type === 'CallExpression' &&
|
||||||
@ -919,8 +920,15 @@ export function doesSceneHaveSweepableSketch(ast: Program) {
|
|||||||
if (pipe.type === 'CallExpression' && pipe.callee.name === 'close') {
|
if (pipe.type === 'CallExpression' && pipe.callee.name === 'close') {
|
||||||
hasClose = true
|
hasClose = true
|
||||||
}
|
}
|
||||||
|
if (pipe.type === 'CallExpression' && pipe.callee.name === 'circle') {
|
||||||
|
hasCircle = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hasStartProfileAt && hasStartSketchOn && hasClose) {
|
if (
|
||||||
|
(hasStartProfileAt || hasCircle) &&
|
||||||
|
hasStartSketchOn &&
|
||||||
|
(hasClose || hasCircle)
|
||||||
|
) {
|
||||||
theMap[node.id.name] = true
|
theMap[node.id.name] = true
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
|
@ -122,7 +122,10 @@ describe('testing changeSketchArguments', () => {
|
|||||||
const changeSketchArgsRetVal = changeSketchArguments(
|
const changeSketchArgsRetVal = changeSketchArguments(
|
||||||
ast,
|
ast,
|
||||||
programMemory,
|
programMemory,
|
||||||
[sourceStart, sourceStart + lineToChange.length],
|
{
|
||||||
|
type: 'sourceRange',
|
||||||
|
sourceRange: [sourceStart, sourceStart + lineToChange.length],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'straight-segment',
|
type: 'straight-segment',
|
||||||
from: [0, 0],
|
from: [0, 0],
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
getNodeFromPath,
|
getNodeFromPath,
|
||||||
getNodeFromPathCurry,
|
getNodeFromPathCurry,
|
||||||
getNodePathFromSourceRange,
|
getNodePathFromSourceRange,
|
||||||
|
getObjExprProperty,
|
||||||
} from 'lang/queryAst'
|
} from 'lang/queryAst'
|
||||||
import {
|
import {
|
||||||
isLiteralArrayOrStatic,
|
isLiteralArrayOrStatic,
|
||||||
@ -57,6 +58,7 @@ import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
|
|||||||
const STRAIGHT_SEGMENT_ERR = new Error(
|
const STRAIGHT_SEGMENT_ERR = new Error(
|
||||||
'Invalid input, expected "straight-segment"'
|
'Invalid input, expected "straight-segment"'
|
||||||
)
|
)
|
||||||
|
const ARC_SEGMENT_ERR = new Error('Invalid input, expected "arc-segment"')
|
||||||
|
|
||||||
export type Coords2d = [number, number]
|
export type Coords2d = [number, number]
|
||||||
|
|
||||||
@ -925,6 +927,177 @@ export const tangentialArcTo: SketchLineHelper = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
export const circle: SketchLineHelper = {
|
||||||
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
||||||
|
if (segmentInput.type !== 'arc-segment') return ARC_SEGMENT_ERR
|
||||||
|
|
||||||
|
const { center, radius } = segmentInput
|
||||||
|
const _node = { ...node }
|
||||||
|
const nodeMeta = getNodeFromPath<PipeExpression>(
|
||||||
|
_node,
|
||||||
|
pathToNode,
|
||||||
|
'PipeExpression'
|
||||||
|
)
|
||||||
|
if (err(nodeMeta)) return nodeMeta
|
||||||
|
|
||||||
|
const { node: pipe } = nodeMeta
|
||||||
|
|
||||||
|
const x = createLiteral(roundOff(center[0], 2))
|
||||||
|
const y = createLiteral(roundOff(center[1], 2))
|
||||||
|
|
||||||
|
const radiusExp = createLiteral(roundOff(radius, 2))
|
||||||
|
|
||||||
|
if (replaceExistingCallback) {
|
||||||
|
const result = replaceExistingCallback([
|
||||||
|
{
|
||||||
|
type: 'arrayInObject',
|
||||||
|
index: 0,
|
||||||
|
key: 'center',
|
||||||
|
argType: 'xAbsolute',
|
||||||
|
expr: x,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'arrayInObject',
|
||||||
|
index: 1,
|
||||||
|
key: 'center',
|
||||||
|
argType: 'yAbsolute',
|
||||||
|
expr: y,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'objectProperty',
|
||||||
|
key: 'radius',
|
||||||
|
argType: 'radius',
|
||||||
|
expr: radiusExp,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
if (err(result)) return result
|
||||||
|
const { callExp, valueUsedInTransform } = result
|
||||||
|
|
||||||
|
const { index: callIndex } = splitPathAtPipeExpression(pathToNode)
|
||||||
|
pipe.body[callIndex] = callExp
|
||||||
|
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode,
|
||||||
|
valueUsedInTransform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Error('not implemented')
|
||||||
|
},
|
||||||
|
updateArgs: ({ node, pathToNode, input }) => {
|
||||||
|
if (input.type !== 'arc-segment') return ARC_SEGMENT_ERR
|
||||||
|
const { center, radius } = input
|
||||||
|
const _node = { ...node }
|
||||||
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, pathToNode)
|
||||||
|
if (err(nodeMeta)) return nodeMeta
|
||||||
|
|
||||||
|
const { node: callExpression, shallowPath } = nodeMeta
|
||||||
|
|
||||||
|
const firstArg = callExpression.arguments?.[0]
|
||||||
|
const newCenter = createArrayExpression([
|
||||||
|
createLiteral(roundOff(center[0])),
|
||||||
|
createLiteral(roundOff(center[1])),
|
||||||
|
])
|
||||||
|
mutateObjExpProp(firstArg, newCenter, 'center')
|
||||||
|
const newRadius = createLiteral(roundOff(radius))
|
||||||
|
mutateObjExpProp(firstArg, newRadius, 'radius')
|
||||||
|
return {
|
||||||
|
modifiedAst: _node,
|
||||||
|
pathToNode: shallowPath,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getTag: getTag(),
|
||||||
|
addTag: addTag(),
|
||||||
|
getConstraintInfo: (callExp: CallExpression, code, pathToNode) => {
|
||||||
|
if (callExp.type !== 'CallExpression') return []
|
||||||
|
const firstArg = callExp.arguments?.[0]
|
||||||
|
if (firstArg.type !== 'ObjectExpression') return []
|
||||||
|
const centerDetails = getObjExprProperty(firstArg, 'center')
|
||||||
|
const radiusDetails = getObjExprProperty(firstArg, 'radius')
|
||||||
|
if (!centerDetails || !radiusDetails) return []
|
||||||
|
if (centerDetails.expr.type !== 'ArrayExpression') return []
|
||||||
|
|
||||||
|
const pathToCenterArrayExpression: PathToNode = [
|
||||||
|
...pathToNode,
|
||||||
|
['arguments', 'CallExpression'],
|
||||||
|
[0, 'index'],
|
||||||
|
['properties', 'ObjectExpression'],
|
||||||
|
[centerDetails.index, 'index'],
|
||||||
|
['value', 'Property'],
|
||||||
|
['elements', 'ArrayExpression'],
|
||||||
|
]
|
||||||
|
const pathToRadiusLiteral: PathToNode = [
|
||||||
|
...pathToNode,
|
||||||
|
['arguments', 'CallExpression'],
|
||||||
|
[0, 'index'],
|
||||||
|
['properties', 'ObjectExpression'],
|
||||||
|
[radiusDetails.index, 'index'],
|
||||||
|
['value', 'Property'],
|
||||||
|
]
|
||||||
|
const pathToXArg: PathToNode = [
|
||||||
|
...pathToCenterArrayExpression,
|
||||||
|
[0, 'index'],
|
||||||
|
]
|
||||||
|
const pathToYArg: PathToNode = [
|
||||||
|
...pathToCenterArrayExpression,
|
||||||
|
[1, 'index'],
|
||||||
|
]
|
||||||
|
|
||||||
|
return [
|
||||||
|
constrainInfo(
|
||||||
|
'radius',
|
||||||
|
isNotLiteralArrayOrStatic(radiusDetails.expr),
|
||||||
|
code.slice(radiusDetails.expr.start, radiusDetails.expr.end),
|
||||||
|
'circle',
|
||||||
|
'radius',
|
||||||
|
[radiusDetails.expr.start, radiusDetails.expr.end],
|
||||||
|
pathToRadiusLiteral
|
||||||
|
),
|
||||||
|
{
|
||||||
|
stdLibFnName: 'circle',
|
||||||
|
type: 'xAbsolute',
|
||||||
|
isConstrained: isNotLiteralArrayOrStatic(
|
||||||
|
centerDetails.expr.elements[0]
|
||||||
|
),
|
||||||
|
sourceRange: [
|
||||||
|
centerDetails.expr.elements[0].start,
|
||||||
|
centerDetails.expr.elements[0].end,
|
||||||
|
],
|
||||||
|
pathToNode: pathToXArg,
|
||||||
|
value: code.slice(
|
||||||
|
centerDetails.expr.elements[0].start,
|
||||||
|
centerDetails.expr.elements[0].end
|
||||||
|
),
|
||||||
|
argPosition: {
|
||||||
|
type: 'arrayInObject',
|
||||||
|
index: 0,
|
||||||
|
key: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
stdLibFnName: 'circle',
|
||||||
|
type: 'yAbsolute',
|
||||||
|
isConstrained: isNotLiteralArrayOrStatic(
|
||||||
|
centerDetails.expr.elements[1]
|
||||||
|
),
|
||||||
|
sourceRange: [
|
||||||
|
centerDetails.expr.elements[1].start,
|
||||||
|
centerDetails.expr.elements[1].end,
|
||||||
|
],
|
||||||
|
pathToNode: pathToYArg,
|
||||||
|
value: code.slice(
|
||||||
|
centerDetails.expr.elements[1].start,
|
||||||
|
centerDetails.expr.elements[1].end
|
||||||
|
),
|
||||||
|
argPosition: {
|
||||||
|
type: 'arrayInObject',
|
||||||
|
index: 1,
|
||||||
|
key: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
export const angledLine: SketchLineHelper = {
|
export const angledLine: SketchLineHelper = {
|
||||||
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
add: ({ node, pathToNode, segmentInput, replaceExistingCallback }) => {
|
||||||
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
if (segmentInput.type !== 'straight-segment') return STRAIGHT_SEGMENT_ERR
|
||||||
@ -1688,16 +1861,28 @@ export const sketchLineHelperMap: { [key: string]: SketchLineHelper } = {
|
|||||||
angledLineToY,
|
angledLineToY,
|
||||||
angledLineThatIntersects,
|
angledLineThatIntersects,
|
||||||
tangentialArcTo,
|
tangentialArcTo,
|
||||||
|
circle,
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
export function changeSketchArguments(
|
export function changeSketchArguments(
|
||||||
node: Program,
|
node: Program,
|
||||||
programMemory: ProgramMemory,
|
programMemory: ProgramMemory,
|
||||||
sourceRange: SourceRange,
|
sourceRangeOrPath:
|
||||||
|
| {
|
||||||
|
type: 'sourceRange'
|
||||||
|
sourceRange: SourceRange
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'path'
|
||||||
|
pathToNode: PathToNode
|
||||||
|
},
|
||||||
input: SegmentInputs
|
input: SegmentInputs
|
||||||
): { modifiedAst: Program; pathToNode: PathToNode } | Error {
|
): { modifiedAst: Program; pathToNode: PathToNode } | Error {
|
||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
const thePath = getNodePathFromSourceRange(_node, sourceRange)
|
const thePath =
|
||||||
|
sourceRangeOrPath.type === 'sourceRange'
|
||||||
|
? getNodePathFromSourceRange(_node, sourceRangeOrPath.sourceRange)
|
||||||
|
: sourceRangeOrPath.pathToNode
|
||||||
const nodeMeta = getNodeFromPath<CallExpression>(_node, thePath)
|
const nodeMeta = getNodeFromPath<CallExpression>(_node, thePath)
|
||||||
if (err(nodeMeta)) return nodeMeta
|
if (err(nodeMeta)) return nodeMeta
|
||||||
|
|
||||||
@ -1875,7 +2060,7 @@ export function replaceSketchLine({
|
|||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
}
|
}
|
||||||
| Error {
|
| Error {
|
||||||
if (![...toolTips, 'intersect'].includes(fnName)) {
|
if (![...toolTips, 'intersect', 'circle'].includes(fnName)) {
|
||||||
return new Error(`The following function name is not tooltip: ${fnName}`)
|
return new Error(`The following function name is not tooltip: ${fnName}`)
|
||||||
}
|
}
|
||||||
const _node = { ...node }
|
const _node = { ...node }
|
||||||
@ -2065,6 +2250,32 @@ function getFirstArgValuesForXYLineFns(callExpression: CallExpression): {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getCircle = (
|
||||||
|
callExp: CallExpression
|
||||||
|
):
|
||||||
|
| {
|
||||||
|
val: [Expr, Expr, Expr]
|
||||||
|
tag?: Expr
|
||||||
|
}
|
||||||
|
| Error => {
|
||||||
|
const firstArg = callExp.arguments[0]
|
||||||
|
if (firstArg.type === 'ObjectExpression') {
|
||||||
|
const centerDetails = getObjExprProperty(firstArg, 'center')
|
||||||
|
const radiusDetails = getObjExprProperty(firstArg, 'radius')
|
||||||
|
const tag = callExp.arguments[2]
|
||||||
|
if (centerDetails?.expr?.type === 'ArrayExpression' && radiusDetails) {
|
||||||
|
return {
|
||||||
|
val: [
|
||||||
|
centerDetails?.expr.elements[0],
|
||||||
|
centerDetails?.expr.elements[1],
|
||||||
|
radiusDetails.expr,
|
||||||
|
],
|
||||||
|
tag,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Error('expected ArrayExpression or ObjectExpression')
|
||||||
|
}
|
||||||
const getAngledLineThatIntersects = (
|
const getAngledLineThatIntersects = (
|
||||||
callExp: CallExpression
|
callExp: CallExpression
|
||||||
):
|
):
|
||||||
@ -2124,5 +2335,8 @@ export function getFirstArg(callExp: CallExpression):
|
|||||||
// TODO probably needs it's own implementation
|
// TODO probably needs it's own implementation
|
||||||
return getFirstArgValuesForXYFns(callExp)
|
return getFirstArgValuesForXYFns(callExp)
|
||||||
}
|
}
|
||||||
|
if (name === 'circle') {
|
||||||
|
return getCircle(callExp)
|
||||||
|
}
|
||||||
return new Error('unexpected call expression: ' + name)
|
return new Error('unexpected call expression: ' + name)
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ export type LineInputsType =
|
|||||||
| 'length'
|
| 'length'
|
||||||
| 'intersectionOffset'
|
| 'intersectionOffset'
|
||||||
| 'intersectionTag'
|
| 'intersectionTag'
|
||||||
|
| 'radius'
|
||||||
|
|
||||||
export type ConstraintType =
|
export type ConstraintType =
|
||||||
| 'equalLength'
|
| 'equalLength'
|
||||||
@ -89,7 +90,10 @@ function createCallWrapper(
|
|||||||
tag?: Expr,
|
tag?: Expr,
|
||||||
valueUsedInTransform?: number
|
valueUsedInTransform?: number
|
||||||
): CreatedSketchExprResult {
|
): CreatedSketchExprResult {
|
||||||
const args = [createFirstArg(tooltip, val), createPipeSubstitution()]
|
const args =
|
||||||
|
tooltip === 'circle'
|
||||||
|
? []
|
||||||
|
: [createFirstArg(tooltip, val), createPipeSubstitution()]
|
||||||
if (tag) {
|
if (tag) {
|
||||||
args.push(tag)
|
args.push(tag)
|
||||||
}
|
}
|
||||||
@ -1735,11 +1739,20 @@ export function transformAstSketchLines({
|
|||||||
pathToNode: _pathToNode,
|
pathToNode: _pathToNode,
|
||||||
referencedSegment,
|
referencedSegment,
|
||||||
fnName: transformTo || (callExp.node.callee.name as ToolTip),
|
fnName: transformTo || (callExp.node.callee.name as ToolTip),
|
||||||
segmentInput: {
|
segmentInput:
|
||||||
type: 'straight-segment',
|
seg.type === 'Circle'
|
||||||
to,
|
? {
|
||||||
from,
|
type: 'arc-segment',
|
||||||
},
|
center: seg.center,
|
||||||
|
radius: seg.radius,
|
||||||
|
from,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
type: 'straight-segment',
|
||||||
|
to,
|
||||||
|
from,
|
||||||
|
},
|
||||||
|
|
||||||
replaceExistingCallback: (rawArgs) =>
|
replaceExistingCallback: (rawArgs) =>
|
||||||
callBack({
|
callBack({
|
||||||
referenceSegName: _referencedSegmentName,
|
referenceSegName: _referencedSegmentName,
|
||||||
@ -1888,6 +1901,6 @@ export function isExprBinaryPart(expr: Expr): expr is BinaryPart {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInputOfType(a: InputArgs, b: LineInputsType): InputArg {
|
function getInputOfType(a: InputArgs, b: LineInputsType | 'radius'): InputArg {
|
||||||
return a.find(({ argType }) => argType === b) || a[0]
|
return a.find(({ argType }) => argType === b) || a[0]
|
||||||
}
|
}
|
||||||
|
@ -35,13 +35,22 @@ interface StraightSegmentInput {
|
|||||||
to: [number, number]
|
to: [number, number]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Inputs for arcs, excluding tangentialArcTo for reasons explain in
|
||||||
|
* the @straightSegmentInput comment */
|
||||||
|
interface ArcSegmentInput {
|
||||||
|
type: 'arc-segment'
|
||||||
|
from: [number, number]
|
||||||
|
center: [number, number]
|
||||||
|
radius: number
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SegmentInputs is a union type that can be either a StraightSegmentInput or an ArcSegmentInput.
|
* SegmentInputs is a union type that can be either a StraightSegmentInput or an ArcSegmentInput.
|
||||||
*
|
*
|
||||||
* - StraightSegmentInput: Represents a straight segment with a starting point (from) and an ending point (to).
|
* - StraightSegmentInput: Represents a straight segment with a starting point (from) and an ending point (to).
|
||||||
* - ArcSegmentInput: Represents an arc segment with a starting point (from), a center point, and a radius.
|
* - ArcSegmentInput: Represents an arc segment with a starting point (from), a center point, and a radius.
|
||||||
*/
|
*/
|
||||||
export type SegmentInputs = StraightSegmentInput // TODO ArcSegmentInput
|
export type SegmentInputs = StraightSegmentInput | ArcSegmentInput
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for adding or replacing a sketch stblib call expression to a sketch.
|
* Interface for adding or replacing a sketch stblib call expression to a sketch.
|
||||||
@ -66,7 +75,14 @@ interface updateArgs extends ModifyAstBase {
|
|||||||
input: SegmentInputs
|
input: SegmentInputs
|
||||||
}
|
}
|
||||||
|
|
||||||
export type InputArgKeys = 'angle' | 'offset' | 'length' | 'to' | 'intersectTag'
|
export type InputArgKeys =
|
||||||
|
| 'angle'
|
||||||
|
| 'offset'
|
||||||
|
| 'length'
|
||||||
|
| 'to'
|
||||||
|
| 'intersectTag'
|
||||||
|
| 'radius'
|
||||||
|
| 'center'
|
||||||
export interface SingleValueInput<T> {
|
export interface SingleValueInput<T> {
|
||||||
type: 'singleValue'
|
type: 'singleValue'
|
||||||
argType: LineInputsType
|
argType: LineInputsType
|
||||||
@ -182,7 +198,12 @@ export type TransformInfo = {
|
|||||||
|
|
||||||
export interface ConstrainInfo {
|
export interface ConstrainInfo {
|
||||||
stdLibFnName: ToolTip
|
stdLibFnName: ToolTip
|
||||||
type: LineInputsType | 'vertical' | 'horizontal' | 'tangentialWithPrevious'
|
type:
|
||||||
|
| LineInputsType
|
||||||
|
| 'vertical'
|
||||||
|
| 'horizontal'
|
||||||
|
| 'tangentialWithPrevious'
|
||||||
|
| 'radius'
|
||||||
isConstrained: boolean
|
isConstrained: boolean
|
||||||
sourceRange: SourceRange
|
sourceRange: SourceRange
|
||||||
pathToNode: PathToNode
|
pathToNode: PathToNode
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export const bracket = `// Shelf Bracket
|
export const bracket = `// Shelf Bracket
|
||||||
// This is a bracket that holds a shelf. It is made of aluminum and is designed to hold a force of 300 lbs. The bracket is 6 inches wide and the force is applied at the end of the shelf, 12 inches from the wall. The bracket has a factor of safety of 1.2. The legs of the bracket are 5 inches and 2 inches long. The thickness of the bracket is calculated from the constraints provided.
|
// This is a bracket that holds a shelf. It is made of aluminum and is designed to hold a force of 300 lbs. The bracket is 6 inches wide and the force is applied at the end of the shelf, 12 inches from the wall. The bracket has a factor of safety of 1.2. The legs of the bracket are 5 inches and 2 inches long. The thickness of the bracket is calculated from the constraints provided.
|
||||||
|
|
||||||
|
|
||||||
// Define constants
|
// Define constants
|
||||||
const sigmaAllow = 35000 // psi (6061-T6 aluminum)
|
const sigmaAllow = 35000 // psi (6061-T6 aluminum)
|
||||||
const width = 6 // inch
|
const width = 6 // inch
|
||||||
@ -11,50 +12,65 @@ const wallMountL = 2 // inches
|
|||||||
const shelfDepth = 12 // Shelf is 12 inches in depth from the wall
|
const shelfDepth = 12 // Shelf is 12 inches in depth from the wall
|
||||||
const moment = shelfDepth * p // assume the force is applied at the end of the shelf to be conservative (lb-in)
|
const moment = shelfDepth * p // assume the force is applied at the end of the shelf to be conservative (lb-in)
|
||||||
|
|
||||||
|
|
||||||
const filletRadius = .375 // inches
|
const filletRadius = .375 // inches
|
||||||
const extFilletRadius = .25 // inches
|
const extFilletRadius = .25 // inches
|
||||||
const mountingHoleDiameter = 0.5 // inches
|
const mountingHoleDiameter = 0.5 // inches
|
||||||
|
|
||||||
|
|
||||||
// Calculate required thickness of bracket
|
// Calculate required thickness of bracket
|
||||||
const thickness = sqrt(moment * factorOfSafety * 6 / (sigmaAllow * width)) // this is the calculation of two brackets holding up the shelf (inches)
|
const thickness = sqrt(moment * factorOfSafety * 6 / (sigmaAllow * width)) // this is the calculation of two brackets holding up the shelf (inches)
|
||||||
|
|
||||||
|
|
||||||
// Sketch the bracket body and fillet the inner and outer edges of the bend
|
// Sketch the bracket body and fillet the inner and outer edges of the bend
|
||||||
const bracketLeg1Sketch = startSketchOn('XY')
|
const bracketLeg1Sketch = startSketchOn('XY')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([shelfMountL-filletRadius, 0], %, $fillet1)
|
|> line([shelfMountL - filletRadius, 0], %, $fillet1)
|
||||||
|> line([0, width], %, $fillet2)
|
|> line([0, width], %, $fillet2)
|
||||||
|> line([-shelfMountL + filletRadius, 0], %)
|
|> line([-shelfMountL + filletRadius, 0], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([1, 1], mountingHoleDiameter/2, %), %)
|
|> hole(circle({
|
||||||
|> hole(circle([shelfMountL-1.5, width-1], mountingHoleDiameter/2, %), %)
|
center: [1, 1],
|
||||||
|> hole(circle([1, width-1], mountingHoleDiameter/2, %), %)
|
radius: mountingHoleDiameter / 2
|
||||||
|> hole(circle([shelfMountL-1.5, 1], mountingHoleDiameter/2, %), %)
|
}, %), %)
|
||||||
|
|> hole(circle({
|
||||||
|
center: [shelfMountL - 1.5, width - 1],
|
||||||
|
radius: mountingHoleDiameter / 2
|
||||||
|
}, %), %)
|
||||||
|
|> hole(circle({
|
||||||
|
center: [1, width - 1],
|
||||||
|
radius: mountingHoleDiameter / 2
|
||||||
|
}, %), %)
|
||||||
|
|> hole(circle({
|
||||||
|
center: [shelfMountL - 1.5, 1],
|
||||||
|
radius: mountingHoleDiameter / 2
|
||||||
|
}, %), %)
|
||||||
|
|
||||||
// Extrude the leg 2 bracket sketch
|
// Extrude the leg 2 bracket sketch
|
||||||
const bracketLeg1Extrude = extrude(thickness, bracketLeg1Sketch)
|
const bracketLeg1Extrude = extrude(thickness, bracketLeg1Sketch)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius: extFilletRadius,
|
radius: extFilletRadius,
|
||||||
tags: [
|
tags: [
|
||||||
getNextAdjacentEdge(fillet1),
|
getNextAdjacentEdge(fillet1),
|
||||||
getNextAdjacentEdge(fillet2)
|
getNextAdjacentEdge(fillet2)
|
||||||
],
|
]
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
// Sketch the fillet arc
|
// Sketch the fillet arc
|
||||||
const filletSketch = startSketchOn('XZ')
|
const filletSketch = startSketchOn('XZ')
|
||||||
|> startProfileAt([0, 0], %)
|
|> startProfileAt([0, 0], %)
|
||||||
|> line([0, thickness], %)
|
|> line([0, thickness], %)
|
||||||
|> arc({
|
|> arc({
|
||||||
angleEnd: 180,
|
angleEnd: 180,
|
||||||
angleStart: 90,
|
angleStart: 90,
|
||||||
radius: filletRadius + thickness,
|
radius: filletRadius + thickness
|
||||||
}, %)
|
}, %)
|
||||||
|> line([thickness, 0], %)
|
|> line([thickness, 0], %)
|
||||||
|> arc({
|
|> arc({
|
||||||
angleEnd: 90,
|
angleEnd: 90,
|
||||||
angleStart: 180,
|
angleStart: 180,
|
||||||
radius: filletRadius,
|
radius: filletRadius
|
||||||
}, %)
|
}, %)
|
||||||
|
|
||||||
// Sketch the bend
|
// Sketch the bend
|
||||||
const filletExtrude = extrude(-width, filletSketch)
|
const filletExtrude = extrude(-width, filletSketch)
|
||||||
@ -76,18 +92,25 @@ const bracketLeg2Sketch = startSketchOn(customPlane)
|
|||||||
|> line([0, -wallMountL], %, $fillet3)
|
|> line([0, -wallMountL], %, $fillet3)
|
||||||
|> line([-width, 0], %, $fillet4)
|
|> line([-width, 0], %, $fillet4)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([1, -1.5], mountingHoleDiameter / 2, %), %)
|
|> hole(circle({
|
||||||
|> hole(circle([5, -1.5], mountingHoleDiameter / 2, %), %)
|
center: [1, -1.5],
|
||||||
|
radius: mountingHoleDiameter / 2
|
||||||
|
}, %), %)
|
||||||
|
|> hole(circle({
|
||||||
|
center: [5, -1.5],
|
||||||
|
radius: mountingHoleDiameter / 2
|
||||||
|
}, %), %)
|
||||||
|
|
||||||
// Extrude the second leg
|
// Extrude the second leg
|
||||||
const bracketLeg2Extrude = extrude(-thickness, bracketLeg2Sketch)
|
const bracketLeg2Extrude = extrude(-thickness, bracketLeg2Sketch)
|
||||||
|> fillet({
|
|> fillet({
|
||||||
radius: extFilletRadius,
|
radius: extFilletRadius,
|
||||||
tags: [
|
tags: [
|
||||||
getNextAdjacentEdge(fillet3),
|
getNextAdjacentEdge(fillet3),
|
||||||
getNextAdjacentEdge(fillet4)
|
getNextAdjacentEdge(fillet4)
|
||||||
],
|
]
|
||||||
}, %)`
|
}, %)
|
||||||
|
`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws Error if the search text is not found in the example code.
|
* @throws Error if the search text is not found in the example code.
|
||||||
|
@ -374,7 +374,7 @@ export function isSelectionLastLine(
|
|||||||
return selectionRanges.codeBasedSelections[i].range[1] === code.length
|
return selectionRanges.codeBasedSelections[i].range[1] === code.length
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isRangeInbetweenCharacters(selectionRanges: Selections) {
|
export function isRangeBetweenCharacters(selectionRanges: Selections) {
|
||||||
return (
|
return (
|
||||||
selectionRanges.codeBasedSelections.length === 1 &&
|
selectionRanges.codeBasedSelections.length === 1 &&
|
||||||
selectionRanges.codeBasedSelections[0].range[0] === 0 &&
|
selectionRanges.codeBasedSelections[0].range[0] === 0 &&
|
||||||
@ -413,6 +413,12 @@ function nodeHasClose(node: CommonASTNode) {
|
|||||||
...node,
|
...node,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function nodeHasCircle(node: CommonASTNode) {
|
||||||
|
return doesPipeHaveCallExp({
|
||||||
|
calleeName: 'circle',
|
||||||
|
...node,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function canSweepSelection(selection: Selections) {
|
export function canSweepSelection(selection: Selections) {
|
||||||
const commonNodes = selection.codeBasedSelections.map((_, i) =>
|
const commonNodes = selection.codeBasedSelections.map((_, i) =>
|
||||||
@ -421,7 +427,8 @@ export function canSweepSelection(selection: Selections) {
|
|||||||
return (
|
return (
|
||||||
!!isSketchPipe(selection) &&
|
!!isSketchPipe(selection) &&
|
||||||
commonNodes.every((n) => !hasSketchPipeBeenExtruded(n.selection, n.ast)) &&
|
commonNodes.every((n) => !hasSketchPipeBeenExtruded(n.selection, n.ast)) &&
|
||||||
commonNodes.every((n) => nodeHasClose(n)) &&
|
(commonNodes.every((n) => nodeHasClose(n)) ||
|
||||||
|
commonNodes.every((n) => nodeHasCircle(n))) &&
|
||||||
commonNodes.every((n) => !nodeHasExtrude(n))
|
commonNodes.every((n) => !nodeHasExtrude(n))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -446,7 +453,7 @@ function canExtrudeSelectionItem(selection: Selections, i: number) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
!!isSketchPipe(isolatedSelection) &&
|
!!isSketchPipe(isolatedSelection) &&
|
||||||
nodeHasClose(commonNode) &&
|
(nodeHasClose(commonNode) || nodeHasCircle(commonNode)) &&
|
||||||
!nodeHasExtrude(commonNode)
|
!nodeHasExtrude(commonNode)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ import { CustomIconName } from 'components/CustomIcon'
|
|||||||
import { DEV } from 'env'
|
import { DEV } from 'env'
|
||||||
import { commandBarMachine } from 'machines/commandBarMachine'
|
import { commandBarMachine } from 'machines/commandBarMachine'
|
||||||
import {
|
import {
|
||||||
canRectangleTool,
|
canRectangleOrCircleTool,
|
||||||
|
isClosedSketch,
|
||||||
isEditingExistingSketch,
|
isEditingExistingSketch,
|
||||||
modelingMachine,
|
modelingMachine,
|
||||||
|
pipeHasCircle,
|
||||||
} from 'machines/modelingMachine'
|
} from 'machines/modelingMachine'
|
||||||
import { EventFrom, StateFrom } from 'xstate'
|
import { EventFrom, StateFrom } from 'xstate'
|
||||||
|
|
||||||
@ -308,7 +310,11 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
|||||||
state.matches('Sketch no face') ||
|
state.matches('Sketch no face') ||
|
||||||
state.matches({
|
state.matches({
|
||||||
Sketch: { 'Rectangle tool': 'Awaiting second corner' },
|
Sketch: { 'Rectangle tool': 'Awaiting second corner' },
|
||||||
}),
|
}) ||
|
||||||
|
state.matches({
|
||||||
|
Sketch: { 'Circle tool': 'Awaiting Radius' },
|
||||||
|
}) ||
|
||||||
|
isClosedSketch(state.context),
|
||||||
title: 'Line',
|
title: 'Line',
|
||||||
hotkey: (state) =>
|
hotkey: (state) =>
|
||||||
state.matches({ Sketch: 'Line tool' }) ? ['Esc', 'L'] : 'L',
|
state.matches({ Sketch: 'Line tool' }) ? ['Esc', 'L'] : 'L',
|
||||||
@ -331,8 +337,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
|||||||
icon: 'arc',
|
icon: 'arc',
|
||||||
status: 'available',
|
status: 'available',
|
||||||
disabled: (state) =>
|
disabled: (state) =>
|
||||||
!isEditingExistingSketch(state.context) &&
|
(!isEditingExistingSketch(state.context) &&
|
||||||
!state.matches({ Sketch: 'Tangential arc to' }),
|
!state.matches({ Sketch: 'Tangential arc to' })) ||
|
||||||
|
pipeHasCircle(state.context),
|
||||||
title: 'Tangential Arc',
|
title: 'Tangential Arc',
|
||||||
hotkey: (state) =>
|
hotkey: (state) =>
|
||||||
state.matches({ Sketch: 'Tangential arc to' }) ? ['Esc', 'A'] : 'A',
|
state.matches({ Sketch: 'Tangential arc to' }) ? ['Esc', 'A'] : 'A',
|
||||||
@ -370,10 +377,24 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'circle-center',
|
id: 'circle-center',
|
||||||
onClick: () => console.error('Center circle not yet implemented'),
|
onClick: ({ modelingState, modelingSend }) =>
|
||||||
|
modelingSend({
|
||||||
|
type: 'change tool',
|
||||||
|
data: {
|
||||||
|
tool: !modelingState.matches({ Sketch: 'Circle tool' })
|
||||||
|
? 'circle'
|
||||||
|
: 'none',
|
||||||
|
},
|
||||||
|
}),
|
||||||
icon: 'circle',
|
icon: 'circle',
|
||||||
status: 'unavailable',
|
status: 'available',
|
||||||
title: 'Center circle',
|
title: 'Center circle',
|
||||||
|
disabled: (state) =>
|
||||||
|
!canRectangleOrCircleTool(state.context) &&
|
||||||
|
!state.matches({ Sketch: 'Circle tool' }),
|
||||||
|
isActive: (state) => state.matches({ Sketch: 'Circle tool' }),
|
||||||
|
hotkey: (state) =>
|
||||||
|
state.matches({ Sketch: 'Circle tool' }) ? ['Esc', 'C'] : 'C',
|
||||||
showTitle: false,
|
showTitle: false,
|
||||||
description: 'Start drawing a circle from its center',
|
description: 'Start drawing a circle from its center',
|
||||||
links: [
|
links: [
|
||||||
@ -389,7 +410,6 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
|||||||
console.error('Three-point circle not yet implemented'),
|
console.error('Three-point circle not yet implemented'),
|
||||||
icon: 'circle',
|
icon: 'circle',
|
||||||
status: 'unavailable',
|
status: 'unavailable',
|
||||||
disabled: () => true,
|
|
||||||
title: 'Three-point circle',
|
title: 'Three-point circle',
|
||||||
showTitle: false,
|
showTitle: false,
|
||||||
description: 'Draw a circle defined by three points',
|
description: 'Draw a circle defined by three points',
|
||||||
@ -411,7 +431,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
|||||||
icon: 'rectangle',
|
icon: 'rectangle',
|
||||||
status: 'available',
|
status: 'available',
|
||||||
disabled: (state) =>
|
disabled: (state) =>
|
||||||
!canRectangleTool(state.context) &&
|
!canRectangleOrCircleTool(state.context) &&
|
||||||
!state.matches({ Sketch: 'Rectangle tool' }),
|
!state.matches({ Sketch: 'Rectangle tool' }),
|
||||||
title: 'Corner rectangle',
|
title: 'Corner rectangle',
|
||||||
hotkey: (state) =>
|
hotkey: (state) =>
|
||||||
|
@ -62,6 +62,8 @@ import { deleteSegment } from 'clientSideScene/ClientSideSceneComp'
|
|||||||
import { executeAst } from 'lang/langHelpers'
|
import { executeAst } from 'lang/langHelpers'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
import { ToolbarModeName } from 'lib/toolbar'
|
import { ToolbarModeName } from 'lib/toolbar'
|
||||||
|
import { quaternionFromUpNForward } from 'clientSideScene/helpers'
|
||||||
|
import { Vector3 } from 'three'
|
||||||
|
|
||||||
export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY'
|
export const MODELING_PERSIST_KEY = 'MODELING_PERSIST_KEY'
|
||||||
|
|
||||||
@ -160,7 +162,12 @@ export interface Store {
|
|||||||
openPanes: SidebarType[]
|
openPanes: SidebarType[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SketchTool = 'line' | 'tangentialArc' | 'rectangle' | 'none'
|
export type SketchTool =
|
||||||
|
| 'line'
|
||||||
|
| 'tangentialArc'
|
||||||
|
| 'rectangle'
|
||||||
|
| 'circle'
|
||||||
|
| 'none'
|
||||||
|
|
||||||
export type ModelingMachineEvent =
|
export type ModelingMachineEvent =
|
||||||
| {
|
| {
|
||||||
@ -213,6 +220,10 @@ export type ModelingMachineEvent =
|
|||||||
type: 'Add rectangle origin'
|
type: 'Add rectangle origin'
|
||||||
data: [x: number, y: number]
|
data: [x: number, y: number]
|
||||||
}
|
}
|
||||||
|
| {
|
||||||
|
type: 'Add circle origin'
|
||||||
|
data: [x: number, y: number]
|
||||||
|
}
|
||||||
| {
|
| {
|
||||||
type: 'xstate.done.actor.animate-to-face'
|
type: 'xstate.done.actor.animate-to-face'
|
||||||
output: SketchDetails
|
output: SketchDetails
|
||||||
@ -246,6 +257,7 @@ export type ModelingMachineEvent =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
| { type: 'Finish rectangle' }
|
| { type: 'Finish rectangle' }
|
||||||
|
| { type: 'Finish circle' }
|
||||||
| { type: 'Artifact graph populated' }
|
| { type: 'Artifact graph populated' }
|
||||||
| { type: 'Artifact graph emptied' }
|
| { type: 'Artifact graph emptied' }
|
||||||
|
|
||||||
@ -314,8 +326,7 @@ export const modelingMachine = setup({
|
|||||||
},
|
},
|
||||||
guards: {
|
guards: {
|
||||||
'Selection is on face': () => false,
|
'Selection is on face': () => false,
|
||||||
'has valid extrude selection': () => false,
|
'has valid sweep selection': () => false,
|
||||||
'has valid revolve selection': () => false,
|
|
||||||
'has valid fillet selection': () => false,
|
'has valid fillet selection': () => false,
|
||||||
'Has exportable geometry': () => false,
|
'Has exportable geometry': () => false,
|
||||||
'has valid selection for deletion': () => false,
|
'has valid selection for deletion': () => false,
|
||||||
@ -464,7 +475,10 @@ export const modelingMachine = setup({
|
|||||||
isEditingExistingSketch({ sketchDetails }),
|
isEditingExistingSketch({ sketchDetails }),
|
||||||
|
|
||||||
'next is rectangle': ({ context: { sketchDetails, currentTool } }) =>
|
'next is rectangle': ({ context: { sketchDetails, currentTool } }) =>
|
||||||
currentTool === 'rectangle' && canRectangleTool({ sketchDetails }),
|
currentTool === 'rectangle' &&
|
||||||
|
canRectangleOrCircleTool({ sketchDetails }),
|
||||||
|
'next is circle': ({ context: { sketchDetails, currentTool } }) =>
|
||||||
|
currentTool === 'circle' && canRectangleOrCircleTool({ sketchDetails }),
|
||||||
'next is line': ({ context }) => context.currentTool === 'line',
|
'next is line': ({ context }) => context.currentTool === 'line',
|
||||||
'next is none': ({ context }) => context.currentTool === 'none',
|
'next is none': ({ context }) => context.currentTool === 'none',
|
||||||
},
|
},
|
||||||
@ -752,6 +766,42 @@ export const modelingMachine = setup({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
'listen for circle origin': ({ context: { sketchDetails } }) => {
|
||||||
|
if (!sketchDetails) return
|
||||||
|
sceneEntitiesManager.createIntersectionPlane()
|
||||||
|
const quaternion = quaternionFromUpNForward(
|
||||||
|
new Vector3(...sketchDetails.yAxis),
|
||||||
|
new Vector3(...sketchDetails.zAxis)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Position the click raycast plane
|
||||||
|
if (sceneEntitiesManager.intersectionPlane) {
|
||||||
|
sceneEntitiesManager.intersectionPlane.setRotationFromQuaternion(
|
||||||
|
quaternion
|
||||||
|
)
|
||||||
|
sceneEntitiesManager.intersectionPlane.position.copy(
|
||||||
|
new Vector3(...(sketchDetails?.origin || [0, 0, 0]))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
sceneInfra.setCallbacks({
|
||||||
|
onClick: (args) => {
|
||||||
|
if (!args) return
|
||||||
|
if (args.mouseEvent.which !== 1) return
|
||||||
|
const { intersectionPoint } = args
|
||||||
|
if (!intersectionPoint?.twoD || !sketchDetails?.sketchPathToNode)
|
||||||
|
return
|
||||||
|
const twoD = args.intersectionPoint?.twoD
|
||||||
|
if (twoD) {
|
||||||
|
sceneInfra.modelingSend({
|
||||||
|
type: 'Add circle origin',
|
||||||
|
data: [twoD.x, twoD.y],
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error('No intersection point found')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
'set up draft rectangle': ({ context: { sketchDetails }, event }) => {
|
'set up draft rectangle': ({ context: { sketchDetails }, event }) => {
|
||||||
if (event.type !== 'Add rectangle origin') return
|
if (event.type !== 'Add rectangle origin') return
|
||||||
if (!sketchDetails || !event.data) return
|
if (!sketchDetails || !event.data) return
|
||||||
@ -764,6 +814,18 @@ export const modelingMachine = setup({
|
|||||||
event.data
|
event.data
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
'set up draft circle': ({ context: { sketchDetails }, event }) => {
|
||||||
|
if (event.type !== 'Add circle origin') return
|
||||||
|
if (!sketchDetails || !event.data) return
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
|
sceneEntitiesManager.setupDraftCircle(
|
||||||
|
sketchDetails.sketchPathToNode,
|
||||||
|
sketchDetails.zAxis,
|
||||||
|
sketchDetails.yAxis,
|
||||||
|
sketchDetails.origin,
|
||||||
|
event.data
|
||||||
|
)
|
||||||
|
},
|
||||||
'set up draft line without teardown': ({ context: { sketchDetails } }) => {
|
'set up draft line without teardown': ({ context: { sketchDetails } }) => {
|
||||||
if (!sketchDetails) return
|
if (!sketchDetails) return
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
@ -1286,14 +1348,14 @@ export const modelingMachine = setup({
|
|||||||
|
|
||||||
Extrude: {
|
Extrude: {
|
||||||
target: 'idle',
|
target: 'idle',
|
||||||
guard: 'has valid extrude selection',
|
guard: 'has valid sweep selection',
|
||||||
actions: ['AST extrude'],
|
actions: ['AST extrude'],
|
||||||
reenter: false,
|
reenter: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
Revolve: {
|
Revolve: {
|
||||||
target: 'idle',
|
target: 'idle',
|
||||||
guard: 'has valid revolve selection',
|
guard: 'has valid sweep selection',
|
||||||
actions: ['AST revolve'],
|
actions: ['AST revolve'],
|
||||||
reenter: false,
|
reenter: false,
|
||||||
},
|
},
|
||||||
@ -1873,10 +1935,43 @@ export const modelingMachine = setup({
|
|||||||
target: 'Tangential arc to',
|
target: 'Tangential arc to',
|
||||||
guard: 'next is tangential arc',
|
guard: 'next is tangential arc',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
target: 'Circle tool',
|
||||||
|
guard: 'next is circle',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
entry: 'assign tool in context',
|
entry: 'assign tool in context',
|
||||||
},
|
},
|
||||||
|
'Circle tool': {
|
||||||
|
on: {
|
||||||
|
'change tool': 'Change Tool',
|
||||||
|
},
|
||||||
|
|
||||||
|
states: {
|
||||||
|
'Awaiting origin': {
|
||||||
|
on: {
|
||||||
|
'Add circle origin': {
|
||||||
|
target: 'Awaiting Radius',
|
||||||
|
actions: 'set up draft circle',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'Awaiting Radius': {
|
||||||
|
on: {
|
||||||
|
'Finish circle': 'Finished Circle',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
'Finished Circle': {
|
||||||
|
always: '#Modeling.Sketch.SketchIdle',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
initial: 'Awaiting origin',
|
||||||
|
entry: 'listen for circle origin',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
initial: 'Init',
|
initial: 'Init',
|
||||||
@ -2014,10 +2109,33 @@ export function isEditingExistingSketch({
|
|||||||
(item) =>
|
(item) =>
|
||||||
item.type === 'CallExpression' && item.callee.name === 'startProfileAt'
|
item.type === 'CallExpression' && item.callee.name === 'startProfileAt'
|
||||||
)
|
)
|
||||||
return hasStartProfileAt && pipeExpression.body.length > 2
|
const hasCircle = pipeExpression.body.some(
|
||||||
|
(item) => item.type === 'CallExpression' && item.callee.name === 'circle'
|
||||||
|
)
|
||||||
|
return (hasStartProfileAt && pipeExpression.body.length > 2) || hasCircle
|
||||||
|
}
|
||||||
|
export function pipeHasCircle({
|
||||||
|
sketchDetails,
|
||||||
|
}: {
|
||||||
|
sketchDetails: SketchDetails | null
|
||||||
|
}): boolean {
|
||||||
|
if (!sketchDetails?.sketchPathToNode) return false
|
||||||
|
const variableDeclaration = getNodeFromPath<VariableDeclarator>(
|
||||||
|
kclManager.ast,
|
||||||
|
sketchDetails.sketchPathToNode,
|
||||||
|
'VariableDeclarator'
|
||||||
|
)
|
||||||
|
if (err(variableDeclaration)) return false
|
||||||
|
if (variableDeclaration.node.type !== 'VariableDeclarator') return false
|
||||||
|
const pipeExpression = variableDeclaration.node.init
|
||||||
|
if (pipeExpression.type !== 'PipeExpression') return false
|
||||||
|
const hasCircle = pipeExpression.body.some(
|
||||||
|
(item) => item.type === 'CallExpression' && item.callee.name === 'circle'
|
||||||
|
)
|
||||||
|
return hasCircle
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canRectangleTool({
|
export function canRectangleOrCircleTool({
|
||||||
sketchDetails,
|
sketchDetails,
|
||||||
}: {
|
}: {
|
||||||
sketchDetails: SketchDetails | null
|
sketchDetails: SketchDetails | null
|
||||||
@ -2032,3 +2150,25 @@ export function canRectangleTool({
|
|||||||
if (err(node)) return false
|
if (err(node)) return false
|
||||||
return node.node?.declarations?.[0]?.init.type !== 'PipeExpression'
|
return node.node?.declarations?.[0]?.init.type !== 'PipeExpression'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** If the sketch contains `close` or `circle` stdlib functions it must be closed */
|
||||||
|
export function isClosedSketch({
|
||||||
|
sketchDetails,
|
||||||
|
}: {
|
||||||
|
sketchDetails: SketchDetails | null
|
||||||
|
}): boolean {
|
||||||
|
const node = getNodeFromPath<VariableDeclaration>(
|
||||||
|
kclManager.ast,
|
||||||
|
sketchDetails?.sketchPathToNode || [],
|
||||||
|
'VariableDeclaration'
|
||||||
|
)
|
||||||
|
// This should not be returning false, and it should be caught
|
||||||
|
// but we need to simulate old behavior to move on.
|
||||||
|
if (err(node)) return false
|
||||||
|
if (node.node?.declarations?.[0]?.init.type !== 'PipeExpression') return false
|
||||||
|
return node.node.declarations[0].init.body.some(
|
||||||
|
(node) =>
|
||||||
|
node.type === 'CallExpression' &&
|
||||||
|
(node.callee.name === 'close' || node.callee.name === 'circle')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -938,6 +938,12 @@ mod tests {
|
|||||||
fn get_autocomplete_snippet_circle() {
|
fn get_autocomplete_snippet_circle() {
|
||||||
let circle_fn: Box<dyn StdLibFn> = Box::new(crate::std::shapes::Circle);
|
let circle_fn: Box<dyn StdLibFn> = Box::new(crate::std::shapes::Circle);
|
||||||
let snippet = circle_fn.to_autocomplete_snippet().unwrap();
|
let snippet = circle_fn.to_autocomplete_snippet().unwrap();
|
||||||
assert_eq!(snippet, r#"circle([${0:3.14}, ${1:3.14}], ${2:3.14}, ${3:%})${}"#);
|
assert_eq!(
|
||||||
|
snippet,
|
||||||
|
r#"circle({
|
||||||
|
center: [${0:3.14}, ${1:3.14}],
|
||||||
|
radius: ${1:3.14},
|
||||||
|
}, ${2:%})${}"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1438,6 +1438,20 @@ pub enum Path {
|
|||||||
/// arc's direction
|
/// arc's direction
|
||||||
ccw: bool,
|
ccw: bool,
|
||||||
},
|
},
|
||||||
|
// TODO: consolidate segment enums, remove Circle. https://github.com/KittyCAD/modeling-app/issues/3940
|
||||||
|
/// a complete arc
|
||||||
|
Circle {
|
||||||
|
#[serde(flatten)]
|
||||||
|
base: BasePath,
|
||||||
|
/// the arc's center
|
||||||
|
#[ts(type = "[number, number]")]
|
||||||
|
center: [f64; 2],
|
||||||
|
/// the arc's radius
|
||||||
|
radius: f64,
|
||||||
|
/// arc's direction
|
||||||
|
// Maybe this one's not needed since it's a full revolution?
|
||||||
|
ccw: bool,
|
||||||
|
},
|
||||||
/// A path that is horizontal.
|
/// A path that is horizontal.
|
||||||
Horizontal {
|
Horizontal {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
@ -1470,6 +1484,7 @@ impl Path {
|
|||||||
Path::Base { base } => base.geo_meta.id,
|
Path::Base { base } => base.geo_meta.id,
|
||||||
Path::TangentialArcTo { base, .. } => base.geo_meta.id,
|
Path::TangentialArcTo { base, .. } => base.geo_meta.id,
|
||||||
Path::TangentialArc { base, .. } => base.geo_meta.id,
|
Path::TangentialArc { base, .. } => base.geo_meta.id,
|
||||||
|
Path::Circle { base, .. } => base.geo_meta.id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1481,6 +1496,7 @@ impl Path {
|
|||||||
Path::Base { base } => base.tag.clone(),
|
Path::Base { base } => base.tag.clone(),
|
||||||
Path::TangentialArcTo { base, .. } => base.tag.clone(),
|
Path::TangentialArcTo { base, .. } => base.tag.clone(),
|
||||||
Path::TangentialArc { base, .. } => base.tag.clone(),
|
Path::TangentialArc { base, .. } => base.tag.clone(),
|
||||||
|
Path::Circle { base, .. } => base.tag.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1492,6 +1508,7 @@ impl Path {
|
|||||||
Path::Base { base } => base,
|
Path::Base { base } => base,
|
||||||
Path::TangentialArcTo { base, .. } => base,
|
Path::TangentialArcTo { base, .. } => base,
|
||||||
Path::TangentialArc { base, .. } => base,
|
Path::TangentialArc { base, .. } => base,
|
||||||
|
Path::Circle { base, .. } => base,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1503,6 +1520,7 @@ impl Path {
|
|||||||
Path::Base { base } => Some(base),
|
Path::Base { base } => Some(base),
|
||||||
Path::TangentialArcTo { base, .. } => Some(base),
|
Path::TangentialArcTo { base, .. } => Some(base),
|
||||||
Path::TangentialArc { base, .. } => Some(base),
|
Path::TangentialArc { base, .. } => Some(base),
|
||||||
|
Path::Circle { base, .. } => Some(base),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2548,7 +2566,7 @@ fn transform = (replicaId) => {
|
|||||||
|
|
||||||
fn layer = () => {
|
fn layer = () => {
|
||||||
return startSketchOn("XY")
|
return startSketchOn("XY")
|
||||||
|> circle([0, 0], 1, %, $tag1)
|
|> circle({ center: [0, 0], radius: 1 }, %, $tag1)
|
||||||
|> extrude(10, %)
|
|> extrude(10, %)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2676,7 +2694,7 @@ fn transform = (replicaId) => {
|
|||||||
|
|
||||||
fn layer = () => {
|
fn layer = () => {
|
||||||
return startSketchOn("XY")
|
return startSketchOn("XY")
|
||||||
|> circle([0, 0], 1, %, $tag1)
|
|> circle({ center: [0, 0], radius: 1 }, %, $tag1)
|
||||||
|> extrude(10, %)
|
|> extrude(10, %)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
---
|
---
|
||||||
source: kcl/src/parser/parser_impl.rs
|
source: kcl/src/parser/parser_impl.rs
|
||||||
|
assertion_line: 3423
|
||||||
expression: actual
|
expression: actual
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"start": 0,
|
"start": 0,
|
||||||
"end": 87,
|
"end": 108,
|
||||||
"body": [
|
"body": [
|
||||||
{
|
{
|
||||||
"type": "VariableDeclaration",
|
"type": "VariableDeclaration",
|
||||||
"type": "VariableDeclaration",
|
"type": "VariableDeclaration",
|
||||||
"start": 0,
|
"start": 0,
|
||||||
"end": 86,
|
"end": 107,
|
||||||
"declarations": [
|
"declarations": [
|
||||||
{
|
{
|
||||||
"type": "VariableDeclarator",
|
"type": "VariableDeclarator",
|
||||||
"start": 6,
|
"start": 6,
|
||||||
"end": 86,
|
"end": 107,
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Identifier",
|
"type": "Identifier",
|
||||||
"start": 6,
|
"start": 6,
|
||||||
@ -27,7 +28,7 @@ expression: actual
|
|||||||
"type": "PipeExpression",
|
"type": "PipeExpression",
|
||||||
"type": "PipeExpression",
|
"type": "PipeExpression",
|
||||||
"start": 17,
|
"start": 17,
|
||||||
"end": 86,
|
"end": 107,
|
||||||
"body": [
|
"body": [
|
||||||
{
|
{
|
||||||
"type": "CallExpression",
|
"type": "CallExpression",
|
||||||
@ -59,7 +60,7 @@ expression: actual
|
|||||||
"type": "CallExpression",
|
"type": "CallExpression",
|
||||||
"type": "CallExpression",
|
"type": "CallExpression",
|
||||||
"start": 44,
|
"start": 44,
|
||||||
"end": 64,
|
"end": 85,
|
||||||
"callee": {
|
"callee": {
|
||||||
"type": "Identifier",
|
"type": "Identifier",
|
||||||
"start": 44,
|
"start": 44,
|
||||||
@ -69,46 +70,81 @@ expression: actual
|
|||||||
},
|
},
|
||||||
"arguments": [
|
"arguments": [
|
||||||
{
|
{
|
||||||
"type": "ArrayExpression",
|
"type": "ObjectExpression",
|
||||||
"type": "ArrayExpression",
|
"type": "ObjectExpression",
|
||||||
"start": 51,
|
"start": 51,
|
||||||
"end": 56,
|
"end": 81,
|
||||||
"elements": [
|
"properties": [
|
||||||
{
|
{
|
||||||
"type": "Literal",
|
"type": "ObjectProperty",
|
||||||
"type": "Literal",
|
"start": 53,
|
||||||
"start": 52,
|
"end": 67,
|
||||||
"end": 53,
|
"key": {
|
||||||
"value": 0,
|
"type": "Identifier",
|
||||||
"raw": "0",
|
"start": 53,
|
||||||
|
"end": 59,
|
||||||
|
"name": "center",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "ArrayExpression",
|
||||||
|
"type": "ArrayExpression",
|
||||||
|
"start": 61,
|
||||||
|
"end": 67,
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 62,
|
||||||
|
"end": 63,
|
||||||
|
"value": 0,
|
||||||
|
"raw": "0",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 65,
|
||||||
|
"end": 66,
|
||||||
|
"value": 0,
|
||||||
|
"raw": "0",
|
||||||
|
"digest": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
"digest": null
|
"digest": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "Literal",
|
"type": "ObjectProperty",
|
||||||
"type": "Literal",
|
"start": 69,
|
||||||
"start": 54,
|
"end": 79,
|
||||||
"end": 55,
|
"key": {
|
||||||
"value": 0,
|
"type": "Identifier",
|
||||||
"raw": "0",
|
"start": 69,
|
||||||
|
"end": 75,
|
||||||
|
"name": "radius",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"start": 77,
|
||||||
|
"end": 79,
|
||||||
|
"value": 22,
|
||||||
|
"raw": "22",
|
||||||
|
"digest": null
|
||||||
|
},
|
||||||
"digest": null
|
"digest": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"digest": null
|
"digest": null
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "Literal",
|
|
||||||
"type": "Literal",
|
|
||||||
"start": 58,
|
|
||||||
"end": 60,
|
|
||||||
"value": 22,
|
|
||||||
"raw": "22",
|
|
||||||
"digest": null
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "PipeSubstitution",
|
"type": "PipeSubstitution",
|
||||||
"type": "PipeSubstitution",
|
"type": "PipeSubstitution",
|
||||||
"start": 62,
|
"start": 83,
|
||||||
"end": 63,
|
"end": 84,
|
||||||
"digest": null
|
"digest": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -118,12 +154,12 @@ expression: actual
|
|||||||
{
|
{
|
||||||
"type": "CallExpression",
|
"type": "CallExpression",
|
||||||
"type": "CallExpression",
|
"type": "CallExpression",
|
||||||
"start": 72,
|
"start": 93,
|
||||||
"end": 86,
|
"end": 107,
|
||||||
"callee": {
|
"callee": {
|
||||||
"type": "Identifier",
|
"type": "Identifier",
|
||||||
"start": 72,
|
"start": 93,
|
||||||
"end": 79,
|
"end": 100,
|
||||||
"name": "extrude",
|
"name": "extrude",
|
||||||
"digest": null
|
"digest": null
|
||||||
},
|
},
|
||||||
@ -131,8 +167,8 @@ expression: actual
|
|||||||
{
|
{
|
||||||
"type": "Literal",
|
"type": "Literal",
|
||||||
"type": "Literal",
|
"type": "Literal",
|
||||||
"start": 80,
|
"start": 101,
|
||||||
"end": 82,
|
"end": 103,
|
||||||
"value": 14,
|
"value": 14,
|
||||||
"raw": "14",
|
"raw": "14",
|
||||||
"digest": null
|
"digest": null
|
||||||
@ -140,8 +176,8 @@ expression: actual
|
|||||||
{
|
{
|
||||||
"type": "PipeSubstitution",
|
"type": "PipeSubstitution",
|
||||||
"type": "PipeSubstitution",
|
"type": "PipeSubstitution",
|
||||||
"start": 84,
|
"start": 105,
|
||||||
"end": 85,
|
"end": 106,
|
||||||
"digest": null
|
"digest": null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -257,8 +257,7 @@ impl Args {
|
|||||||
&self,
|
&self,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
[f64; 2],
|
crate::std::shapes::CircleData,
|
||||||
f64,
|
|
||||||
crate::std::shapes::SketchSurfaceOrGroup,
|
crate::std::shapes::SketchSurfaceOrGroup,
|
||||||
Option<TagDeclarator>,
|
Option<TagDeclarator>,
|
||||||
),
|
),
|
||||||
@ -628,6 +627,7 @@ fn from_user_val<T: DeserializeOwned>(arg: &KclValue) -> Option<T> {
|
|||||||
impl_from_arg_via_json!(super::sketch::AngledLineData);
|
impl_from_arg_via_json!(super::sketch::AngledLineData);
|
||||||
impl_from_arg_via_json!(super::sketch::AngledLineToData);
|
impl_from_arg_via_json!(super::sketch::AngledLineToData);
|
||||||
impl_from_arg_via_json!(super::sketch::AngledLineThatIntersectsData);
|
impl_from_arg_via_json!(super::sketch::AngledLineThatIntersectsData);
|
||||||
|
impl_from_arg_via_json!(super::shapes::CircleData);
|
||||||
impl_from_arg_via_json!(super::sketch::ArcData);
|
impl_from_arg_via_json!(super::sketch::ArcData);
|
||||||
impl_from_arg_via_json!(super::sketch::TangentialArcData);
|
impl_from_arg_via_json!(super::sketch::TangentialArcData);
|
||||||
impl_from_arg_via_json!(super::sketch::BezierData);
|
impl_from_arg_via_json!(super::sketch::BezierData);
|
||||||
|
@ -50,7 +50,7 @@ pub async fn int(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// const sketch001 = startSketchOn('XZ')
|
/// const sketch001 = startSketchOn('XZ')
|
||||||
/// |> circle([0, 0], 2, %)
|
/// |> circle({ center: [0, 0], radius: 2 }, %)
|
||||||
/// const extrude001 = extrude(5, sketch001)
|
/// const extrude001 = extrude(5, sketch001)
|
||||||
///
|
///
|
||||||
/// const pattern01 = patternTransform(int(ceil(5 / 2)), (id) => {
|
/// const pattern01 = patternTransform(int(ceil(5 / 2)), (id) => {
|
||||||
|
@ -148,13 +148,10 @@ pub(crate) async fn do_post_extrude(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut edge_id = None;
|
let edge_id = sketch_group.value.iter().find_map(|segment| match segment {
|
||||||
for segment in sketch_group.value.iter() {
|
Path::ToPoint { base } | Path::Circle { base, .. } => Some(base.geo_meta.id),
|
||||||
if let Path::ToPoint { base } = segment {
|
_ => None,
|
||||||
edge_id = Some(base.geo_meta.id);
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let Some(edge_id) = edge_id else {
|
let Some(edge_id) = edge_id else {
|
||||||
return Err(KclError::Type(KclErrorDetails {
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
@ -237,7 +234,7 @@ pub(crate) async fn do_post_extrude(
|
|||||||
.flat_map(|path| {
|
.flat_map(|path| {
|
||||||
if let Some(Some(actual_face_id)) = face_id_map.get(&path.get_base().geo_meta.id) {
|
if let Some(Some(actual_face_id)) = face_id_map.get(&path.get_base().geo_meta.id) {
|
||||||
match path {
|
match path {
|
||||||
Path::TangentialArc { .. } | Path::TangentialArcTo { .. } => {
|
Path::TangentialArc { .. } | Path::TangentialArcTo { .. } | Path::Circle { .. } => {
|
||||||
let extrude_surface = ExtrudeSurface::ExtrudeArc(crate::executor::ExtrudeArc {
|
let extrude_surface = ExtrudeSurface::ExtrudeArc(crate::executor::ExtrudeArc {
|
||||||
face_id: *actual_face_id,
|
face_id: *actual_face_id,
|
||||||
tag: path.get_base().tag.clone(),
|
tag: path.get_base().tag.clone(),
|
||||||
|
@ -43,7 +43,7 @@ pub async fn helix(_exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// const part001 = startSketchOn('XY')
|
/// const part001 = startSketchOn('XY')
|
||||||
/// |> circle([5, 5], 10, %)
|
/// |> circle({ center: [5, 5], radius: 10 }, %)
|
||||||
/// |> extrude(10, %)
|
/// |> extrude(10, %)
|
||||||
/// |> helix({
|
/// |> helix({
|
||||||
/// angleStart: 0,
|
/// angleStart: 0,
|
||||||
|
@ -92,10 +92,10 @@ pub async fn loft(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
///
|
///
|
||||||
/// const circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
/// const circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
||||||
/// |> circle([0, 100], 50, %)
|
/// |> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
///
|
///
|
||||||
/// const circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
/// const circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
||||||
/// |> circle([0, 100], 20, %)
|
/// |> circle({ center: [0, 100], radius: 20 }, %)
|
||||||
///
|
///
|
||||||
/// loft([squareSketch, circleSketch0, circleSketch1])
|
/// loft([squareSketch, circleSketch0, circleSketch1])
|
||||||
/// ```
|
/// ```
|
||||||
@ -111,10 +111,10 @@ pub async fn loft(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
///
|
///
|
||||||
/// const circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
/// const circleSketch0 = startSketchOn(offsetPlane('XY', 75))
|
||||||
/// |> circle([0, 100], 50, %)
|
/// |> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
///
|
///
|
||||||
/// const circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
/// const circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
||||||
/// |> circle([0, 100], 20, %)
|
/// |> circle({ center: [0, 100], radius: 20 }, %)
|
||||||
///
|
///
|
||||||
/// loft([squareSketch, circleSketch0, circleSketch1], {
|
/// loft([squareSketch, circleSketch0, circleSketch1], {
|
||||||
/// // This can be set to override the automatically determined
|
/// // This can be set to override the automatically determined
|
||||||
|
@ -113,7 +113,7 @@ pub async fn pi(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kcl
|
|||||||
/// const circumference = 70
|
/// const circumference = 70
|
||||||
///
|
///
|
||||||
/// const exampleSketch = startSketchOn("XZ")
|
/// const exampleSketch = startSketchOn("XZ")
|
||||||
/// |> circle([0, 0], circumference/ (2 * pi()), %)
|
/// |> circle({ center: [0, 0], radius: circumference/ (2 * pi()) }, %)
|
||||||
///
|
///
|
||||||
/// const example = extrude(5, exampleSketch)
|
/// const example = extrude(5, exampleSketch)
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -38,7 +38,7 @@ use crate::{
|
|||||||
ast::types::FunctionExpression,
|
ast::types::FunctionExpression,
|
||||||
docs::StdLibFn,
|
docs::StdLibFn,
|
||||||
errors::KclError,
|
errors::KclError,
|
||||||
executor::{ExecState, KclValue, ProgramMemory, SketchGroup, SketchSurface},
|
executor::{ExecState, KclValue, ProgramMemory},
|
||||||
std::kcl_stdlib::KclStdLibFn,
|
std::kcl_stdlib::KclStdLibFn,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ pub async fn pattern_transform(exec_state: &mut ExecState, args: Args) -> Result
|
|||||||
/// // Each layer is just a pretty thin cylinder.
|
/// // Each layer is just a pretty thin cylinder.
|
||||||
/// fn layer = () => {
|
/// fn layer = () => {
|
||||||
/// return startSketchOn("XY") // or some other plane idk
|
/// return startSketchOn("XY") // or some other plane idk
|
||||||
/// |> circle([0, 0], 1, %, $tag1)
|
/// |> circle({ center: [0, 0], radius: 1 }, %, $tag1)
|
||||||
/// |> extrude(h, %)
|
/// |> extrude(h, %)
|
||||||
/// }
|
/// }
|
||||||
/// // The vase is 100 layers tall.
|
/// // The vase is 100 layers tall.
|
||||||
@ -326,7 +326,7 @@ pub async fn pattern_linear_2d(_exec_state: &mut ExecState, args: Args) -> Resul
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// const exampleSketch = startSketchOn('XZ')
|
/// const exampleSketch = startSketchOn('XZ')
|
||||||
/// |> circle([0, 0], 1, %)
|
/// |> circle({ center: [0, 0], radius: 1 }, %)
|
||||||
/// |> patternLinear2d({
|
/// |> patternLinear2d({
|
||||||
/// axis: [1, 0],
|
/// axis: [1, 0],
|
||||||
/// repetitions: 6,
|
/// repetitions: 6,
|
||||||
@ -656,7 +656,7 @@ pub async fn pattern_circular_3d(exec_state: &mut ExecState, args: Args) -> Resu
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// const exampleSketch = startSketchOn('XZ')
|
/// const exampleSketch = startSketchOn('XZ')
|
||||||
/// |> circle([0, 0], 1, %)
|
/// |> circle({ center: [0, 0], radius: 1 }, %)
|
||||||
///
|
///
|
||||||
/// const example = extrude(-5, exampleSketch)
|
/// const example = extrude(-5, exampleSketch)
|
||||||
/// |> patternCircular3d({
|
/// |> patternCircular3d({
|
||||||
|
@ -77,7 +77,7 @@ pub async fn offset_plane(_exec_state: &mut ExecState, args: Args) -> Result<Kcl
|
|||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
///
|
///
|
||||||
/// const circleSketch = startSketchOn(offsetPlane('XY', 150))
|
/// const circleSketch = startSketchOn(offsetPlane('XY', 150))
|
||||||
/// |> circle([0, 100], 50, %)
|
/// |> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
///
|
///
|
||||||
/// loft([squareSketch, circleSketch])
|
/// loft([squareSketch, circleSketch])
|
||||||
/// ```
|
/// ```
|
||||||
@ -93,7 +93,7 @@ pub async fn offset_plane(_exec_state: &mut ExecState, args: Args) -> Result<Kcl
|
|||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
///
|
///
|
||||||
/// const circleSketch = startSketchOn(offsetPlane('XZ', 150))
|
/// const circleSketch = startSketchOn(offsetPlane('XZ', 150))
|
||||||
/// |> circle([0, 100], 50, %)
|
/// |> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
///
|
///
|
||||||
/// loft([squareSketch, circleSketch])
|
/// loft([squareSketch, circleSketch])
|
||||||
/// ```
|
/// ```
|
||||||
@ -109,7 +109,7 @@ pub async fn offset_plane(_exec_state: &mut ExecState, args: Args) -> Result<Kcl
|
|||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
///
|
///
|
||||||
/// const circleSketch = startSketchOn(offsetPlane('YZ', 150))
|
/// const circleSketch = startSketchOn(offsetPlane('YZ', 150))
|
||||||
/// |> circle([0, 100], 50, %)
|
/// |> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
///
|
///
|
||||||
/// loft([squareSketch, circleSketch])
|
/// loft([squareSketch, circleSketch])
|
||||||
/// ```
|
/// ```
|
||||||
@ -125,7 +125,7 @@ pub async fn offset_plane(_exec_state: &mut ExecState, args: Args) -> Result<Kcl
|
|||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
///
|
///
|
||||||
/// const circleSketch = startSketchOn(offsetPlane('-XZ', -150))
|
/// const circleSketch = startSketchOn(offsetPlane('-XZ', -150))
|
||||||
/// |> circle([0, 100], 50, %)
|
/// |> circle({ center: [0, 100], radius: 50 }, %)
|
||||||
///
|
///
|
||||||
/// loft([squareSketch, circleSketch])
|
/// loft([squareSketch, circleSketch])
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -134,7 +134,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// // A donut shape.
|
/// // A donut shape.
|
||||||
/// const sketch001 = startSketchOn('XY')
|
/// const sketch001 = startSketchOn('XY')
|
||||||
/// |> circle([15, 0], 5, %)
|
/// |> circle({ center: [15, 0], radius: 5 }, %)
|
||||||
/// |> revolve({
|
/// |> revolve({
|
||||||
/// angle: 360,
|
/// angle: 360,
|
||||||
/// axis: 'y'
|
/// axis: 'y'
|
||||||
@ -186,7 +186,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// |> extrude(20, %)
|
/// |> extrude(20, %)
|
||||||
///
|
///
|
||||||
/// const sketch001 = startSketchOn(box, "END")
|
/// const sketch001 = startSketchOn(box, "END")
|
||||||
/// |> circle([10,10], 4, %)
|
/// |> circle({ center: [10,10], radius: 4 }, %)
|
||||||
/// |> revolve({
|
/// |> revolve({
|
||||||
/// angle: -90,
|
/// angle: -90,
|
||||||
/// axis: 'y'
|
/// axis: 'y'
|
||||||
@ -203,7 +203,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// |> extrude(20, %)
|
/// |> extrude(20, %)
|
||||||
///
|
///
|
||||||
/// const sketch001 = startSketchOn(box, "END")
|
/// const sketch001 = startSketchOn(box, "END")
|
||||||
/// |> circle([10,10], 4, %)
|
/// |> circle({ center: [10,10], radius: 4 }, %)
|
||||||
/// |> revolve({
|
/// |> revolve({
|
||||||
/// angle: 90,
|
/// angle: 90,
|
||||||
/// axis: getOppositeEdge(revolveAxis)
|
/// axis: getOppositeEdge(revolveAxis)
|
||||||
@ -220,7 +220,7 @@ pub async fn revolve(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// |> extrude(20, %)
|
/// |> extrude(20, %)
|
||||||
///
|
///
|
||||||
/// const sketch001 = startSketchOn(box, "END")
|
/// const sketch001 = startSketchOn(box, "END")
|
||||||
/// |> circle([10,10], 4, %)
|
/// |> circle({ center: [10,10], radius: 4 }, %)
|
||||||
/// |> revolve({
|
/// |> revolve({
|
||||||
/// angle: 90,
|
/// angle: 90,
|
||||||
/// axis: getOppositeEdge(revolveAxis),
|
/// axis: getOppositeEdge(revolveAxis),
|
||||||
|
@ -2,14 +2,21 @@
|
|||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use derive_docs::stdlib;
|
use derive_docs::stdlib;
|
||||||
|
use kcmc::each_cmd as mcmd;
|
||||||
|
use kcmc::length_unit::LengthUnit;
|
||||||
|
use kcmc::shared::Angle;
|
||||||
|
use kcmc::shared::Point2d as KPoint2d;
|
||||||
|
use kcmc::ModelingCmd;
|
||||||
|
use kittycad_modeling_cmds as kcmc;
|
||||||
|
use kittycad_modeling_cmds::shared::PathSegment;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::types::TagDeclarator,
|
ast::types::TagDeclarator,
|
||||||
errors::KclError,
|
errors::KclError,
|
||||||
executor::{ExecState, KclValue},
|
executor::{BasePath, ExecState, GeoMeta, KclValue, Path, SketchGroup, SketchSurface},
|
||||||
std::{Args, SketchGroup, SketchSurface},
|
std::Args,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A sketch surface or a sketch group.
|
/// A sketch surface or a sketch group.
|
||||||
@ -21,12 +28,24 @@ pub enum SketchSurfaceOrGroup {
|
|||||||
SketchGroup(Box<SketchGroup>),
|
SketchGroup(Box<SketchGroup>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Data for drawing an circle
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
|
#[ts(export)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
// TODO: make sure the docs on the args below are correct.
|
||||||
|
pub struct CircleData {
|
||||||
|
/// The center of the circle.
|
||||||
|
pub center: [f64; 2],
|
||||||
|
/// The circle radius
|
||||||
|
pub radius: f64,
|
||||||
|
}
|
||||||
|
|
||||||
/// Sketch a circle.
|
/// Sketch a circle.
|
||||||
pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (center, radius, sketch_surface_or_group, tag): ([f64; 2], f64, SketchSurfaceOrGroup, Option<TagDeclarator>) =
|
let (data, sketch_surface_or_group, tag): (CircleData, SketchSurfaceOrGroup, Option<TagDeclarator>) =
|
||||||
args.get_circle_args()?;
|
args.get_circle_args()?;
|
||||||
|
|
||||||
let sketch_group = inner_circle(center, radius, sketch_surface_or_group, tag, exec_state, args).await?;
|
let sketch_group = inner_circle(data, sketch_surface_or_group, tag, exec_state, args).await?;
|
||||||
Ok(KclValue::new_user_val(sketch_group.meta.clone(), sketch_group))
|
Ok(KclValue::new_user_val(sketch_group.meta.clone(), sketch_group))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +54,7 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// const exampleSketch = startSketchOn("-XZ")
|
/// const exampleSketch = startSketchOn("-XZ")
|
||||||
/// |> circle([0, 0], 10, %)
|
/// |> circle({ center: [0, 0], radius: 10 }, %)
|
||||||
///
|
///
|
||||||
/// const example = extrude(5, exampleSketch)
|
/// const example = extrude(5, exampleSketch)
|
||||||
/// ```
|
/// ```
|
||||||
@ -47,7 +66,7 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// |> line([0, 30], %)
|
/// |> line([0, 30], %)
|
||||||
/// |> line([-30, 0], %)
|
/// |> line([-30, 0], %)
|
||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
/// |> hole(circle([0, 15], 5, %), %)
|
/// |> hole(circle({ center: [0, 15], radius: 5 }, %), %)
|
||||||
///
|
///
|
||||||
/// const example = extrude(5, exampleSketch)
|
/// const example = extrude(5, exampleSketch)
|
||||||
/// ```
|
/// ```
|
||||||
@ -55,8 +74,7 @@ pub async fn circle(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
name = "circle",
|
name = "circle",
|
||||||
}]
|
}]
|
||||||
async fn inner_circle(
|
async fn inner_circle(
|
||||||
center: [f64; 2],
|
data: CircleData,
|
||||||
radius: f64,
|
|
||||||
sketch_surface_or_group: SketchSurfaceOrGroup,
|
sketch_surface_or_group: SketchSurfaceOrGroup,
|
||||||
tag: Option<TagDeclarator>,
|
tag: Option<TagDeclarator>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
@ -66,8 +84,8 @@ async fn inner_circle(
|
|||||||
SketchSurfaceOrGroup::SketchSurface(surface) => surface,
|
SketchSurfaceOrGroup::SketchSurface(surface) => surface,
|
||||||
SketchSurfaceOrGroup::SketchGroup(group) => group.on,
|
SketchSurfaceOrGroup::SketchGroup(group) => group.on,
|
||||||
};
|
};
|
||||||
let mut sketch_group = crate::std::sketch::inner_start_profile_at(
|
let sketch_group = crate::std::sketch::inner_start_profile_at(
|
||||||
[center[0] + radius, center[1]],
|
[data.center[0] + data.radius, data.center[1]],
|
||||||
sketch_surface,
|
sketch_surface,
|
||||||
None,
|
None,
|
||||||
exec_state,
|
exec_state,
|
||||||
@ -75,19 +93,55 @@ async fn inner_circle(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Call arc.
|
let angle_start = Angle::zero();
|
||||||
sketch_group = crate::std::sketch::inner_arc(
|
let angle_end = Angle::turn();
|
||||||
crate::std::sketch::ArcData::AnglesAndRadius {
|
|
||||||
angle_start: 0.0,
|
let id = uuid::Uuid::new_v4();
|
||||||
angle_end: 360.0,
|
|
||||||
radius,
|
args.batch_modeling_cmd(
|
||||||
},
|
id,
|
||||||
sketch_group,
|
ModelingCmd::from(mcmd::ExtendPath {
|
||||||
tag,
|
path: sketch_group.id.into(),
|
||||||
args.clone(),
|
segment: PathSegment::Arc {
|
||||||
|
start: angle_start,
|
||||||
|
end: angle_end,
|
||||||
|
center: KPoint2d::from(data.center).map(LengthUnit),
|
||||||
|
radius: data.radius.into(),
|
||||||
|
relative: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Call close.
|
let current_path = Path::Circle {
|
||||||
crate::std::sketch::inner_close(sketch_group, None, args).await
|
base: BasePath {
|
||||||
|
from: data.center,
|
||||||
|
to: data.center,
|
||||||
|
tag: tag.clone(),
|
||||||
|
geo_meta: GeoMeta {
|
||||||
|
id,
|
||||||
|
metadata: args.source_range.into(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
radius: data.radius,
|
||||||
|
center: data.center,
|
||||||
|
ccw: angle_start.to_degrees() < angle_end.to_degrees(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut new_sketch_group = sketch_group.clone();
|
||||||
|
if let Some(tag) = &tag {
|
||||||
|
new_sketch_group.add_tag(tag, ¤t_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_sketch_group.value.push(current_path);
|
||||||
|
|
||||||
|
args.batch_modeling_cmd(
|
||||||
|
id,
|
||||||
|
ModelingCmd::from(mcmd::ClosePath {
|
||||||
|
path_id: new_sketch_group.id,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(new_sketch_group)
|
||||||
}
|
}
|
||||||
|
@ -116,11 +116,11 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// |> extrude(65, %)
|
/// |> extrude(65, %)
|
||||||
///
|
///
|
||||||
/// const thing1 = startSketchOn(case, 'end')
|
/// const thing1 = startSketchOn(case, 'end')
|
||||||
/// |> circle([-size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [-size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// const thing2 = startSketchOn(case, 'end')
|
/// const thing2 = startSketchOn(case, 'end')
|
||||||
/// |> circle([size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// // We put "case" in the shell function to shell the entire object.
|
/// // We put "case" in the shell function to shell the entire object.
|
||||||
@ -139,11 +139,11 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// |> extrude(65, %)
|
/// |> extrude(65, %)
|
||||||
///
|
///
|
||||||
/// const thing1 = startSketchOn(case, 'end')
|
/// const thing1 = startSketchOn(case, 'end')
|
||||||
/// |> circle([-size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [-size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// const thing2 = startSketchOn(case, 'end')
|
/// const thing2 = startSketchOn(case, 'end')
|
||||||
/// |> circle([size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// // We put "thing1" in the shell function to shell the end face of the object.
|
/// // We put "thing1" in the shell function to shell the end face of the object.
|
||||||
@ -164,11 +164,11 @@ pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// |> extrude(65, %)
|
/// |> extrude(65, %)
|
||||||
///
|
///
|
||||||
/// const thing1 = startSketchOn(case, 'end')
|
/// const thing1 = startSketchOn(case, 'end')
|
||||||
/// |> circle([-size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [-size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// const thing2 = startSketchOn(case, 'end')
|
/// const thing2 = startSketchOn(case, 'end')
|
||||||
/// |> circle([size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// // We put "thing1" and "thing2" in the shell function to shell the end face of the object.
|
/// // We put "thing1" and "thing2" in the shell function to shell the end face of the object.
|
||||||
@ -292,11 +292,11 @@ pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
|||||||
/// |> extrude(65, %)
|
/// |> extrude(65, %)
|
||||||
///
|
///
|
||||||
/// const thing1 = startSketchOn(case, 'end')
|
/// const thing1 = startSketchOn(case, 'end')
|
||||||
/// |> circle([-size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [-size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// const thing2 = startSketchOn(case, 'end')
|
/// const thing2 = startSketchOn(case, 'end')
|
||||||
/// |> circle([size / 2, -size / 2], 25, %)
|
/// |> circle({ center: [size / 2, -size / 2], radius: 25 }, %)
|
||||||
/// |> extrude(50, %)
|
/// |> extrude(50, %)
|
||||||
///
|
///
|
||||||
/// hollow(0.5, case)
|
/// hollow(0.5, case)
|
||||||
|
@ -2050,8 +2050,8 @@ pub async fn hole(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// |> line([5, 0], %)
|
/// |> line([5, 0], %)
|
||||||
/// |> line([0, -5], %)
|
/// |> line([0, -5], %)
|
||||||
/// |> close(%)
|
/// |> close(%)
|
||||||
/// |> hole(circle([1, 1], .25, %), %)
|
/// |> hole(circle({ center: [1, 1], radius: .25 }, %), %)
|
||||||
/// |> hole(circle([1, 4], .25, %), %)
|
/// |> hole(circle({ center: [1, 4], radius: .25 }, %), %)
|
||||||
///
|
///
|
||||||
/// const example = extrude(1, exampleSketch)
|
/// const example = extrude(1, exampleSketch)
|
||||||
/// ```
|
/// ```
|
||||||
@ -2068,7 +2068,7 @@ pub async fn hole(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// const exampleSketch = startSketchOn('-XZ')
|
/// const exampleSketch = startSketchOn('-XZ')
|
||||||
/// |> circle([0, 0], 3, %)
|
/// |> circle({ center: [0, 0], radius: 3 }, %)
|
||||||
/// |> hole(squareHoleSketch(), %)
|
/// |> hole(squareHoleSketch(), %)
|
||||||
/// const example = extrude(1, exampleSketch)
|
/// const example = extrude(1, exampleSketch)
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -1028,10 +1028,13 @@ const tabs_r = startSketchOn({
|
|||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> line([-10, -5], %)
|
|> line([-10, -5], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([
|
|> hole(circle({
|
||||||
width / 2 + thk + hole_diam,
|
center: [
|
||||||
length / 2 - hole_diam
|
width / 2 + thk + hole_diam,
|
||||||
], hole_diam / 2, %), %)
|
length / 2 - hole_diam
|
||||||
|
],
|
||||||
|
radius: hole_diam / 2
|
||||||
|
}, %), %)
|
||||||
|> extrude(-thk, %)
|
|> extrude(-thk, %)
|
||||||
|> patternLinear3d({
|
|> patternLinear3d({
|
||||||
axis: [0, -1, 0],
|
axis: [0, -1, 0],
|
||||||
@ -1052,10 +1055,13 @@ const tabs_l = startSketchOn({
|
|||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> line([10, -5], %)
|
|> line([10, -5], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([
|
|> hole(circle({
|
||||||
-width / 2 - thk - hole_diam,
|
center: [
|
||||||
length / 2 - hole_diam
|
-width / 2 - thk - hole_diam,
|
||||||
], hole_diam / 2, %), %)
|
length / 2 - hole_diam
|
||||||
|
],
|
||||||
|
radius: hole_diam / 2
|
||||||
|
}, %), %)
|
||||||
|> extrude(-thk, %)
|
|> extrude(-thk, %)
|
||||||
|> patternLinear3d({
|
|> patternLinear3d({
|
||||||
axis: [0, -1, 0],
|
axis: [0, -1, 0],
|
||||||
@ -1148,10 +1154,13 @@ const tabs_r = startSketchOn({
|
|||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> line([-10, -5], %)
|
|> line([-10, -5], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([
|
|> hole(circle({
|
||||||
width / 2 + thk + hole_diam,
|
center: [
|
||||||
length / 2 - hole_diam
|
width / 2 + thk + hole_diam,
|
||||||
], hole_diam / 2, %), %)
|
length / 2 - hole_diam
|
||||||
|
],
|
||||||
|
radius: hole_diam / 2
|
||||||
|
}, %), %)
|
||||||
|> extrude(-thk, %)
|
|> extrude(-thk, %)
|
||||||
|> patternLinear3d({
|
|> patternLinear3d({
|
||||||
axis: [0, -1, 0],
|
axis: [0, -1, 0],
|
||||||
@ -1172,10 +1181,13 @@ const tabs_l = startSketchOn({
|
|||||||
|> line([0, -10], %)
|
|> line([0, -10], %)
|
||||||
|> line([10, -5], %)
|
|> line([10, -5], %)
|
||||||
|> close(%)
|
|> close(%)
|
||||||
|> hole(circle([
|
|> hole(circle({
|
||||||
-width / 2 - thk - hole_diam,
|
center: [
|
||||||
length / 2 - hole_diam
|
-width / 2 - thk - hole_diam,
|
||||||
], hole_diam / 2, %), %)
|
length / 2 - hole_diam
|
||||||
|
],
|
||||||
|
radius: hole_diam / 2
|
||||||
|
}, %), %)
|
||||||
|> extrude(-thk, %)
|
|> extrude(-thk, %)
|
||||||
|> patternLinear3d({
|
|> patternLinear3d({
|
||||||
axis: [0, -1, 0],
|
axis: [0, -1, 0],
|
||||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 136 KiB |