Struct scad_tree::Scad

source ·
pub struct Scad {
    pub op: ScadOp,
    pub children: Vec<Scad>,
}
Expand description

A tree of OpenSCAD operations.

Should not need to construct manually in end user code. We have macros and functions to do it for us.

Fields§

§op: ScadOp§children: Vec<Scad>

Implementations§

source§

impl Scad

source

pub fn external_circle_chamfer( size: f64, oversize: f64, radius: f64, degrees: f64, segments: u64 ) -> Self

Creates a curved chamfer shape.

size: The size of the angled part of the chamfer profile.

oversize: How much non-angled part there is on the chamfer.

radius: The radius of the arc that the chamfer takes.

degrees: The degrees of the arc that the chamfer is extruded through.

segments: The number of segments in a circle.

return: The mesh.

source

pub fn external_cylinder_chamfer( size: f64, oversize: f64, radius: f64, height: f64, segments: u64, center: bool ) -> Self

Creates two external circle chamfers for chamfering a cylinder.

size: The size of the angled part of the chamfer profile.

oversize: How much non-angled part there is on the chamfer.

radius: The radius of the cylinder to be chamfered.

height: The height of the cylinder to be chamfered.

segments: The number of segments in a circle.

return: The mesh.

source

pub fn save(&self, path: &str)

Examples found in repository?
examples/bottle.rs (line 38)
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
fn make_cap() {
    let cylinder = Polyhedron::cylinder(23.0, 12.0, 128).into_scad();
    let mut tap = metric_thread::tap(40, 14.0, 128, false, false);
    tap = translate!([0.0, 0.0, 2.0], tap;);

    let cap = cylinder - tap;
    cap.save("output/bottle_cap.scad");
}

fn make_bottle() {
    let mut outside_profile = Pt2s::new();
    outside_profile.push(Pt2::new(0.0, 125.0));
    outside_profile.append(&mut dim2::cubic_bezier(
        Pt2::new(19.0, 125.0),
        Pt2::new(22.5, 110.0),
        Pt2::new(32.5, 105.0),
        Pt2::new(32.5, 100.0),
        6,
    ));
    outside_profile.append(&mut dim2::quadratic_bezier(
        Pt2::new(32.5, 5.0),
        Pt2::new(32.5, 0.0),
        Pt2::new(27.5, 0.0),
        6,
    ));
    outside_profile.push(Pt2::new(0.0, 0.0));

    let mut inside_profile = Pt2s::new();
    inside_profile.push(Pt2::new(0.0, 140.0));
    inside_profile.push(Pt2::new(16.0, 140.0));
    inside_profile.append(&mut dim2::cubic_bezier(
        Pt2::new(16.0, 125.0),
        Pt2::new(20.5, 110.0),
        Pt2::new(30.5, 105.0),
        Pt2::new(30.5, 100.0),
        6,
    ));
    inside_profile.append(&mut dim2::quadratic_bezier(
        Pt2::new(30.5, 7.0),
        Pt2::new(30.5, 2.0),
        Pt2::new(25.5, 2.0),
        6,
    ));
    inside_profile.push(Pt2::new(0.0, 2.0));

    let outside = rotate_extrude!(angle=360.0, convexity=10, fn=128, polygon!(outside_profile););
    let inside = rotate_extrude!(angle=360.0, convexity=10, fn=128, polygon!(inside_profile););

    let threaded_rod = translate!([0.0,0.0,120.0], metric_thread::threaded_rod(40, 15.0, 128, 0.0, 180.0, false, false););

    let bottle = outside + threaded_rod - inside;

    bottle.save("output/bottle.scad");
}
More examples
Hide additional examples
examples/cup.rs (line 75)
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
fn main() {
    let segments: u64 = 36;
    let slices: u64 = 12;

    let mut cup_blank_profile = Pt2s::new();
    cup_blank_profile.push(Pt2::new(0.0, 0.0));
    cup_blank_profile.append(&mut dim2::cubic_bezier(
        Pt2::new(40.0, 0.0),
        Pt2::new(40.0, 33.0),
        Pt2::new(60.0, 66.0),
        Pt2::new(60.0, 100.0),
        slices,
    ));
    cup_blank_profile.push(Pt2::new(0.0, 100.0));

    let cup_blank = rotate_extrude!(angle=360.0, convexity=2, fn=segments,
        polygon!(cup_blank_profile);
    );

    let mut cup_inner_profile = Pt2s::new();
    cup_inner_profile.push(Pt2::new(0.0, 3.0));
    cup_inner_profile.append(&mut dim2::cubic_bezier(
        Pt2::new(37.0, 3.0),
        Pt2::new(37.0, 33.0),
        Pt2::new(57.0, 66.0),
        Pt2::new(57.0, 103.0),
        slices,
    ));
    cup_inner_profile.push(Pt2::new(0.0, 103.0));

    let cup_inner = rotate_extrude!(angle=360.0, convexity=1, fn=segments,
        polygon!(cup_inner_profile);
    );

    let handle_path = dim3::cubic_bezier(
        Pt3::new(37.0, 20.0, 0.0),
        Pt3::new(70.0, 30.0, 0.0),
        Pt3::new(120.0, 90.0, 0.0),
        Pt3::new(57.0, 90.0, 0.0),
        segments,
    );

    let handle_profile = dim2::rounded_rect(8.0, 20.0, 2.5, segments, true);
    let mut handle = Polyhedron::sweep(&handle_profile, &handle_path, 0.0, false);
    handle.rotate_x(90.0);

    let cup = cup_blank + handle.into_scad_with_convexity(2) - cup_inner;

    cup.save("output/cup.scad");
}
examples/scad_tree.rs (line 51)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
fn main() {
    // The Scad struct and the ScadOp enum are the main types in the library.
    // This tree is the difference of a cube and a sphere but it's a little
    // unwieldy to write.
    Scad {
        op: ScadOp::Difference,
        children: vec![
            Scad {
                op: ScadOp::Cube {
                    size: Pt3::new(2.0, 2.0, 2.0),
                    center: false,
                },
                children: Vec::new(),
            },
            Scad {
                op: ScadOp::Sphere {
                    radius: 1.0,
                    fa: None,
                    fs: None,
                    fn_: Some(24),
                },
                children: Vec::new(),
            },
        ],
    }
    .save("output/scad_tree1.scad");

    // Thats where the macros come in. All the operations from the 2D, 3D, and transformations
    // sections of the OpenSCAD cheatsheet (https://openscad.org/cheatsheet) are covered by macros.
    // All of the macros except scad_file expand to a Scad struct literal like above. The scad_file
    // macro specifies the file to save and allows setting $fa, $fs, and $fn globally.

    // This snippet of macro code produces the tree above but is a bit easier to read and write.
    // If you squint hard enough it resembles OpenSCAD code!
    scad_file!(
        "output/scad_tree2.scad",
        difference!(
            cube!(2.0);
            sphere!(1.0, fn=24);
        );
    );

    // Maybe your not a fan of OpenSCAD structured code. Since each macro expands to part of a tree
    // it's easy to save to variables or return a Scad from a funtion. This code produces the same
    // output as the above.
    let cube = cube!(2.0);
    let sphere = sphere!(1.0, fn=24);
    let difference = difference!(cube; sphere;);
    difference.save("output/scad_tree3.scad");

    // Maybe you want it to look like math!
    let cube = cube!(2.0);
    let sphere = sphere!(1.0, fn=24);
    (cube - sphere).save("output/scad_tree4.scad");
}

Trait Implementations§

source§

impl Add<Scad> for Scad

§

type Output = Scad

The resulting type after applying the + operator.
source§

fn add(self, rhs: Self) -> Self::Output

Performs the + operation. Read more
source§

impl Clone for Scad

source§

fn clone(&self) -> Scad

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Display for Scad

Since we are outputting text we leverage the Display trait to format output.

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Scad> for Scad

source§

fn eq(&self, other: &Scad) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Sub<Scad> for Scad

§

type Output = Scad

The resulting type after applying the - operator.
source§

fn sub(self, rhs: Self) -> Self::Output

Performs the - operation. Read more
source§

impl StructuralPartialEq for Scad

Auto Trait Implementations§

§

impl RefUnwindSafe for Scad

§

impl Send for Scad

§

impl Sync for Scad

§

impl Unpin for Scad

§

impl UnwindSafe for Scad

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.