Tag enhancements (#3143)

* start

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* more

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* enhancements

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* get plane data

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* more

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fmt

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add lint rule

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2024-07-27 22:56:46 -07:00
committed by GitHub
parent 2ec68e3c73
commit fb7b2be427
55 changed files with 40977 additions and 18867 deletions

View File

@ -0,0 +1,74 @@
// A mounting bracket for the Focusrite Scarlett Solo audio interface
// This is a bracket that holds an audio device underneath a desk or shelf. The audio device has dimensions of 144mm wide, 80mm length and 45mm depth with fillets of 6mm. This mounting bracket is designed to be 3D printed with PLA material
// define constants in mm
const radius = 6.0
const width = 144.0
const length = 80.0
const depth = 45.0
const thk = 4
const holeDiam = 5
const tabLength = 25
const tabWidth = 12
const tabThk = 4
// define a rectangular shape func
fn rectShape = (pos, w, l) => {
const rr = startSketchOn('xy')
|> startProfileAt([pos[0] - (w / 2), pos[1] - (l / 2)], %)
|> lineTo([pos[0] + w / 2, pos[1] - (l / 2)], %, $edge01)
|> lineTo([pos[0] + w / 2, pos[1] + l / 2], %, $edge02)
|> lineTo([pos[0] - (w / 2), pos[1] + l / 2], %, $edge03)
|> close(%, $edge04)
return rr
}
// define the bracket plane
const bracketPlane = {
plane: {
origin: { x: 0, y: length / 2 + thk, z: 0 },
x_axis: { x: 1, y: 0, z: 0 },
y_axis: { x: 0, y: 0, z: 1 },
z_axis: { x: 0, y: -1, z: 0 }
}
}
// build the bracket sketch around the body
fn bracketSketch = (w, d, t) => {
const s = startSketchOn(bracketPlane)
|> startProfileAt([-w / 2 - t, d + t], %)
|> lineTo([-w / 2 - t, -t], %, $edge1)
|> lineTo([w / 2 + t, -t], %, $edge2)
|> lineTo([w / 2 + t, d + t], %, $edge3)
|> lineTo([w / 2, d + t], %, $edge4)
|> lineTo([w / 2, 0], %, $edge5)
|> lineTo([-w / 2, 0], %, $edge6)
|> lineTo([-w / 2, d + t], %, $edge7)
|> close(%, $edge8)
|> extrude(length + 2 * thk, %)
return s
}
// build the body of the bracket
const bs = bracketSketch(width, depth, thk)
const bracketBody = bs
|> fillet({
radius: radius,
tags: [
getNextAdjacentEdge(bs.sketchGroup.tags.edge7),
getNextAdjacentEdge(bs.sketchGroup.tags.edge2),
getNextAdjacentEdge(bs.sketchGroup.tags.edge3),
getNextAdjacentEdge(bs.sketchGroup.tags.edge6)
]
}, %)
// sketch on the face
const retBack = startSketchOn(bs, bs.sketchGroup.tags.edge4)
|> startProfileAt([length / 2 + thk, 0], %)
|> line([0, thk], %)
|> line([-thk, 0], %)
|> line([0, -thk], %)
|> close(%)
|> extrude(width - 40, %)

View File

@ -56,10 +56,10 @@ const bracketBody = bs
|> fillet({
radius: radius,
tags: [
getNextAdjacentEdge(bs.tags.edge7, %),
getNextAdjacentEdge(bs.tags.edge2, %),
getNextAdjacentEdge(bs.tags.edge3, %),
getNextAdjacentEdge(bs.tags.edge6, %)
getNextAdjacentEdge(bs.tags.edge7),
getNextAdjacentEdge(bs.tags.edge2),
getNextAdjacentEdge(bs.tags.edge3),
getNextAdjacentEdge(bs.tags.edge6)
]
}, %)
@ -88,8 +88,8 @@ const tabsR = startSketchOn(tabPlane)
|> fillet({
radius: holeDiam / 2,
tags: [
getNextAdjacentEdge(edge12, %),
getNextAdjacentEdge(edge13, %)
getNextAdjacentEdge(edge12),
getNextAdjacentEdge(edge13)
]
}, %)
|> patternLinear3d({
@ -113,8 +113,8 @@ const tabsL = startSketchOn(tabPlane)
|> fillet({
radius: holeDiam / 2,
tags: [
getNextAdjacentEdge(edge21, %),
getNextAdjacentEdge(edge22, %)
getNextAdjacentEdge(edge21),
getNextAdjacentEdge(edge22)
]
}, %)
|> patternLinear3d({

View File

@ -18,7 +18,7 @@ fn layer = () => {
|> extrude(h, %)
// |> fillet({
// radius: h / 2.01,
// tags: ["tag1", getOppositeEdge(tag1, %)]
// tags: [tag1, getOppositeEdge(tag1)]
// }, %)
}
// The vase is 100 layers tall.

View File

@ -24,7 +24,7 @@ const plumbus1 =
|> extrude(plumbusLen, %)
|> fillet({
radius: 5,
tags: [c1.tags.arc_tag, getOppositeEdge(c1.tags.arc_tag, %)]
tags: [c1.tags.arc_tag, getOppositeEdge(c1.tags.arc_tag)]
}, %)
const c2 = circl(200, a)
const plumbus0 =
@ -32,7 +32,7 @@ const plumbus0 =
|> extrude(plumbusLen, %)
|> fillet({
radius: 5,
tags: [c2.tags.arc_tag, getOppositeEdge(c2.tags.arc_tag, %)]
tags: [c2.tags.arc_tag, getOppositeEdge(c2.tags.arc_tag)]
}, %)

View File

@ -3,12 +3,12 @@ fn rect = (origin) => {
|> startProfileAt(origin, %)
|> angledLine([0, 191.26], %, $rectangleSegmentA001)
|> angledLine([
segAng(rectangleSegmentA001, %) - 90,
segAng(rectangleSegmentA001) - 90,
196.99
], %, $rectangleSegmentB001)
|> angledLine([
segAng(rectangleSegmentA001, %),
-segLen(rectangleSegmentA001, %)
segAng(rectangleSegmentA001),
-segLen(rectangleSegmentA001)
], %, $rectangleSegmentC001)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)

View File

@ -259,7 +259,7 @@ async fn serial_test_basic_fillet_cube_end() {
|> line([0, -10], %, $thing2)
|> close(%)
|> extrude(10, %)
|> fillet({radius: 2, tags: [thing, getOppositeEdge(thing, %)]}, %)
|> fillet({radius: 2, tags: [thing, getOppositeEdge(thing)]}, %)
"#;
@ -276,7 +276,7 @@ async fn serial_test_basic_fillet_cube_close_opposite() {
|> line([0, -10], %, $thing2)
|> close(%, $thing3)
|> extrude(10, %)
|> fillet({radius: 2, tags: [thing3, getOppositeEdge(thing3, %)]}, %)
|> fillet({radius: 2, tags: [thing3, getOppositeEdge(thing3)]}, %)
"#;
@ -297,7 +297,7 @@ async fn serial_test_basic_fillet_cube_next_adjacent() {
|> line([0, -10], %, $thing2)
|> close(%, $thing3)
|> extrude(10, %)
|> fillet({radius: 2, tags: [getNextAdjacentEdge(thing3, %)]}, %)
|> fillet({radius: 2, tags: [getNextAdjacentEdge(thing3)]}, %)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
@ -317,7 +317,7 @@ async fn serial_test_basic_fillet_cube_previous_adjacent() {
|> line([0, -10], %, $thing2)
|> close(%, $thing3)
|> extrude(10, %)
|> fillet({radius: 2, tags: [getPreviousAdjacentEdge(thing3, %)]}, %)
|> fillet({radius: 2, tags: [getPreviousAdjacentEdge(thing3)]}, %)
"#;
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
@ -380,7 +380,7 @@ async fn serial_test_execute_with_angled_line() {
|> line([15.1, 2.48], %)
|> line([3.15, -9.85], %, $seg01)
|> line([-15.17, -4.1], %)
|> angledLine([segAng(seg01, %), 12.35], %)
|> angledLine([segAng(seg01), 12.35], %)
|> line([-13.02, 10.03], %)
|> close(%)
|> extrude(4, %)
@ -1395,10 +1395,10 @@ const part = rectShape([0, 0], 20, 20)
|> fillet({
radius: 4,
tags: [
getNextAdjacentEdge(edge1, %),
getNextAdjacentEdge(edge2, %),
getNextAdjacentEdge(edge3, %),
getNextAdjacentEdge(edge4, %)
getNextAdjacentEdge(edge1),
getNextAdjacentEdge(edge2),
getNextAdjacentEdge(edge3),
getNextAdjacentEdge(edge4)
]
}, %)
"#;
@ -1627,7 +1627,7 @@ const sketch001 = startSketchOn(box, "end")
|> line([2, 0], %)
|> line([0, 10], %)
|> close(%)
|> revolve({ axis: getOppositeEdge(revolveAxis, box), angle: 90 }, %)
|> revolve({ axis: getOppositeEdge(revolveAxis), angle: 90 }, %)
"#;
@ -1651,7 +1651,7 @@ const sketch001 = startSketchOn(box, revolveAxis)
|> line([2, 0], %)
|> line([0, 10], %)
|> close(%)
|> revolve({ axis: getEdge(revolveAxis, box), angle: 90 }, %)
|> revolve({ axis: revolveAxis, angle: 90 }, %)
"#;
@ -1660,7 +1660,7 @@ const sketch001 = startSketchOn(box, revolveAxis)
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"engine: KclErrorDetails { source_ranges: [SourceRange([346, 404])], message: "Modeling command failed: [ApiError { error_code: InternalEngine, message: \"Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis\" }]" }"#
r#"engine: KclErrorDetails { source_ranges: [SourceRange([346, 390])], message: "Modeling command failed: [ApiError { error_code: InternalEngine, message: \"Solid3D revolve failed: sketch profile must lie entirely on one side of the revolution axis\" }]" }"#
);
}
@ -1678,7 +1678,7 @@ const sketch001 = startSketchOn(box, "END")
|> circle([10,10], 4, %)
|> revolve({
angle: 90,
axis: getOppositeEdge(revolveAxis, box)
axis: getOppositeEdge(revolveAxis)
}, %)
"#;
@ -1804,19 +1804,19 @@ fn pentagon = (len) => {
|> startProfileAt([-len / 2, -len / 2], %)
|> angledLine({ angle: 0, length: len }, %, $a)
|> angledLine({
angle: segAng(a, %) + 180 - 108,
angle: segAng(a) + 180 - 108,
length: len
}, %, $b)
|> angledLine({
angle: segAng(b, %) + 180 - 108,
angle: segAng(b) + 180 - 108,
length: len
}, %, $c)
|> angledLine({
angle: segAng(c, %) + 180 - 108,
angle: segAng(c) + 180 - 108,
length: len
}, %, $d)
|> angledLine({
angle: segAng(d, %) + 180 - 108,
angle: segAng(d) + 180 - 108,
length: len
}, %)
@ -1831,7 +1831,7 @@ const plumbus0 = circle0
|> extrude(10, %)
|> fillet({
radius: 0.5,
tags: [circle0.tags.arc1, getOppositeEdge(circle0.tags.arc1, %)]
tags: [circle0.tags.arc1, getOppositeEdge(circle0.tags.arc1)]
}, %)
const circle1 = make_circle(p, p.sketchGroup.tags.b, [0, 0], 2.5)
@ -1839,7 +1839,7 @@ const plumbus1 = circle1
|> extrude(10, %)
|> fillet({
radius: 0.5,
tags: [circle1.tags.arc1, getOppositeEdge(circle1.tags.arc1, %)]
tags: [circle1.tags.arc1, getOppositeEdge(circle1.tags.arc1)]
}, %)
"#;
@ -1922,11 +1922,11 @@ const bracket = startSketchOn('XY')
|> extrude(width, %)
|> fillet({
radius: filletR,
tags: [getNextAdjacentEdge(innerEdge, %)]
tags: [getNextAdjacentEdge(innerEdge)]
}, %)
|> fillet({
radius: filletR + thickness,
tags: [getNextAdjacentEdge(outerEdge, %)]
tags: [getNextAdjacentEdge(outerEdge)]
}, %)
"#;
@ -1934,7 +1934,7 @@ const bracket = startSketchOn('XY')
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"engine: KclErrorDetails { source_ranges: [SourceRange([1332, 1436])], message: "Modeling command failed: [ApiError { error_code: BadRequest, message: \"Fillet failed\" }]" }"#
r#"engine: KclErrorDetails { source_ranges: [SourceRange([1329, 1430])], message: "Modeling command failed: [ApiError { error_code: BadRequest, message: \"Fillet failed\" }]" }"#
);
}
@ -2147,13 +2147,13 @@ const bracket = startSketchOn('XY')
|> fillet({
radius: filletR,
tags: [
getPreviousAdjacentEdge(innerEdge, %)
getPreviousAdjacentEdge(innerEdge)
]
}, %)
|> fillet({
radius: filletR + thickness,
tags: [
getPreviousAdjacentEdge(outerEdge, %)
getPreviousAdjacentEdge(outerEdge)
]
}, %)
@ -2247,15 +2247,15 @@ const sketch001 = startSketchOn("XZ")
const baseExtrusion = extrude(width, sketch001)
|> fillet({
radius: cornerFilletRad,
tags: [cornerFillet1, cornerFillet2, getOppositeEdge(cornerFillet1, %), getOppositeEdge(cornerFillet2, %)],
tags: [cornerFillet1, cornerFillet2, getOppositeEdge(cornerFillet1), getOppositeEdge(cornerFillet2)],
}, %)
|> fillet({
radius: filletRad,
tags: [getPreviousAdjacentEdge(fillet1, %), getPreviousAdjacentEdge(fillet2, %)]
tags: [getPreviousAdjacentEdge(fillet1), getPreviousAdjacentEdge(fillet2)]
}, %)
|> fillet({
radius: filletRad + thickness,
tags: [getNextAdjacentEdge(fillet1, %), getNextAdjacentEdge(fillet2, %)],
tags: [getNextAdjacentEdge(fillet1), getNextAdjacentEdge(fillet2)],
}, %)
"#;
@ -2299,15 +2299,15 @@ const sketch001 = startSketchOn("XZ")
const baseExtrusion = extrude(width, sketch001)
|> chamfer({
length: cornerChamferRad,
tags: [cornerChamfer1, cornerChamfer2, getOppositeEdge(cornerChamfer1, %), getOppositeEdge(cornerChamfer2, %)],
tags: [cornerChamfer1, cornerChamfer2, getOppositeEdge(cornerChamfer1), getOppositeEdge(cornerChamfer2)],
}, %)
|> chamfer({
length: chamferRad,
tags: [getPreviousAdjacentEdge(chamfer1, %), getPreviousAdjacentEdge(chamfer2, %)]
tags: [getPreviousAdjacentEdge(chamfer1), getPreviousAdjacentEdge(chamfer2)]
}, %)
|> chamfer({
length: chamferRad + thickness,
tags: [getNextAdjacentEdge(chamfer1, %), getNextAdjacentEdge(chamfer2, %)],
tags: [getNextAdjacentEdge(chamfer1), getNextAdjacentEdge(chamfer2)],
}, %)
"#;
@ -2325,7 +2325,7 @@ async fn serial_test_engine_error_source_range_on_last_command() {
|> startProfileAt([61.74, 206.13], %)
|> xLine(305.11, %, $seg01)
|> yLine(-291.85, %)
|> xLine(-segLen(seg01, %), %)
|> xLine(-segLen(seg01), %)
|> lineTo([profileStartX(%), profileStartY(%)], %)
|> close(%)
|> extrude(40.14, %)
@ -2339,7 +2339,7 @@ async fn serial_test_engine_error_source_range_on_last_command() {
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"engine: KclErrorDetails { source_ranges: [SourceRange([259, 315])], message: "Modeling command failed: [ApiError { error_code: InternalEngine, message: \"Invalid brep after shell operation\" }]" }"#
r#"engine: KclErrorDetails { source_ranges: [SourceRange([256, 312])], message: "Modeling command failed: [ApiError { error_code: InternalEngine, message: \"Invalid brep after shell operation\" }]" }"#
);
}
@ -2359,7 +2359,7 @@ const part001 = cube([0,0], 20)
|> extrude(20, %)
|> fillet({
radius: 10,
tags: [getOppositeEdge(line1,%)]
tags: [getOppositeEdge(line1)]
}, %)
const pattn1 = patternLinear3d({
@ -2394,7 +2394,7 @@ const part001 = cube([0,0], 20)
|> extrude(20, %)
|> fillet({
radius: 10,
tags: [getOppositeEdge(line1,%)]
tags: [getOppositeEdge(line1)]
}, %)
const pattn2 = patternCircular3d({axis: [0,0, 1], center: [-20, -20, -20], repetitions: 4, arcDegrees: 360, rotateDuplicates: false}, part001)
@ -2425,7 +2425,7 @@ const part001 = cube([0,0], 20)
|> extrude(20, %)
|> chamfer({
length: 10,
tags: [getOppositeEdge(line1,%)]
tags: [getOppositeEdge(line1)]
}, %)
const pattn2 = patternCircular3d({axis: [0,0, 1], center: [-20, -20, -20], repetitions: 4, arcDegrees: 360, rotateDuplicates: false}, part001)
@ -2456,7 +2456,7 @@ const part001 = cube([0,0], 20)
|> extrude(20, %)
|> chamfer({
length: 10,
tags: [line1, getOppositeEdge(line1,%)]
tags: [line1, getOppositeEdge(line1)]
}, %, $chamfer1)
@ -2466,7 +2466,7 @@ const part001 = cube([0,0], 20)
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"type: KclErrorDetails { source_ranges: [SourceRange([271, 359])], message: "You can only tag one edge at a time with a tagged chamfer. Either delete the tag for the chamfer fn if you don't need it OR separate into individual chamfer functions for each tag." }"#
r#"type: KclErrorDetails { source_ranges: [SourceRange([271, 357])], message: "You can only tag one edge at a time with a tagged chamfer. Either delete the tag for the chamfer fn if you don't need it OR separate into individual chamfer functions for each tag." }"#
);
}
@ -2483,12 +2483,12 @@ async fn serial_test_sketch_on_face_of_chamfer() {
return sg
}
const part001 = cube([0,0], 20)
|> close(%, 'line1')
|> close(%, $line1)
|> extrude(20, %)
|> chamfer({
length: 10,
tags: [getOppositeEdge('line1',%)]
}, %, 'chamfer1')
tags: [getOppositeEdge(line1)]
}, %, $chamfer1)
const sketch001 = startSketchOn(part001, 'chamfer1')
|> startProfileAt([4.28, 3.83], %)
@ -2515,11 +2515,11 @@ async fn serial_test_duplicate_tags_should_error() {
|> startProfileAt([-len / 2, -len / 2], %)
|> angledLine({ angle: 0, length: len }, %, $a)
|> angledLine({
angle: segAng(a, %) + 120,
angle: segAng(a) + 120,
length: len
}, %, $b)
|> angledLine({
angle: segAng(b, %) + 120,
angle: segAng(b) + 120,
length: len
}, %, $a)
}
@ -2531,7 +2531,7 @@ let p = triangle(200)
assert!(result.is_err());
assert_eq!(
result.err().unwrap().to_string(),
r#"value already defined: KclErrorDetails { source_ranges: [SourceRange([317, 319]), SourceRange([332, 345])], message: "Cannot redefine `a`" }"#
r#"value already defined: KclErrorDetails { source_ranges: [SourceRange([311, 313]), SourceRange([326, 339])], message: "Cannot redefine `a`" }"#
);
}
@ -2542,6 +2542,17 @@ async fn serial_test_global_tags() {
twenty_twenty::assert_image("tests/executor/outputs/global_tags.png", &result, MIN_DIFF);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_extrude_inside_fn_with_tags() {
let code = include_str!("inputs/extrude-inside-fn-with-tags.kcl");
let result = execute_and_snapshot(code, UnitLength::Mm).await.unwrap();
twenty_twenty::assert_image(
"tests/executor/outputs/extrude-inside-fn-with-tags.png",
&result,
MIN_DIFF,
);
}
#[tokio::test(flavor = "multi_thread")]
async fn serial_test_pattern_vase() {
let code = include_str!("inputs/pattern_vase.kcl");

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB