scad/
lib.rs

1/*!
2    This crate is used to generate openscad models using rust.
3
4    ## Usage
5
6    First, let's look at a simple example of the crate being used.
7
8    ```
9    //"Import" the module along with the macros
10    #[macro_use]
11    extern crate scad;
12
13    //Avoid having to write scad:: everywhere
14    use scad::*;
15
16    pub fn main() {
17        //Create an scad file object for storing the scad objects. This
18        //allows us to set things like the detail level ($fn) for the models.
19        let mut scad_file = ScadFile::new();
20
21        //Sets the $fn variable in scad which controls the detail level of things
22        //like spheres. Look at the scad wiki for details
23        scad_file.set_detail(50);
24
25        //Create an scad object
26        let mut cube = scad!(Translate(vec3(2.0, 2.0, 3.0)); {
27            scad!(Cube(vec3(2.0,1.0,4.0)))
28        });
29
30        //Create a cylinder with a height of 10 and a diameter of 3 mm
31        let cylinder = scad!(Cylinder(10., Diameter(3.)));
32
33        //Add the cylinder to the cubes translation.
34        cube.add_child(cylinder);
35
36        //Add the cube object to the file
37        scad_file.add_object(cube.clone());
38
39        //Save the scad code to a file
40        scad_file.write_to_file(String::from("out.scad"));
41
42        //You can also print the code for the object manually since it's just a string
43        println!("{}", scad!(Cube(vec3(5., 3.,  2.))).get_code());
44    }
45    ```
46
47    Which will print the following openscad code
48    ```OpenSCAD
49    translate([2,2,3])
50    {
51        cube([2,1,4]);
52        Cylinder(h=10, r=3);
53    }
54    ```
55
56    ## The `scad!` macro
57    The most important part of the crate is the `scad!` macro. The first parameter
58    of the macro is the element type of the object we want to create which should be 
59    an instance of the `ScadElement` enum. If you only want to create a single scad
60    object, you can simply end the macro invocation after the parent like this:
61
62
63    ```
64    # #[macro_use]
65    # extern crate scad;
66    # use scad::*;
67
68    # fn main(){
69        scad!(Cube(vec3(10., 10., 10.)));
70    # }
71    ```
72
73    A lot of times, you want to add more elements as children to an scad object. For example
74    when translating a cube. If you want to add children to the object, add a `;` after the
75    element type and surround all the children in `{}`. The children should be instances
76    of the `ScadObject`. The children should be separated by `;`.
77
78    ```
79    # #[macro_use]
80    # extern crate scad;
81    # use scad::*;
82
83    # fn main() {
84        let child = scad!(Cylinder(10., Radius(3.)));
85
86        scad!(Difference;{
87            //A child can be another call to the scad! macro
88            scad!(Cube(vec3(1., 2., 3.))),
89            //or a variable that is an scad object
90            child,
91            //Or even a function that returns an scad object
92            get_child(),
93        });
94
95        fn get_child() -> ScadObject
96        {
97        //...
98        # scad!(Union)
99        }
100    # }
101    ```
102
103    ## Object parameters
104    Almost all `ScadElements` take additional parameters that describe them. They 
105    are enum parameters so you specify them as you would with enums. Some parameters
106    are regular built in types like `f32` but there are some special ones which are 
107    described below.
108
109    ### Vectors
110    The most common parameter is a vector. This library uses the nalgebra crate for vectors
111    but writing `na::Vector3::new(x, y, z)` each time you want a vector is tedious which is 
112    why the library contains the functions `vec3(x, y, z)` and `vec2(x, y)`. They are simply
113    functions that call the equivalent nalgebra constructor.
114
115    ### Circle radii and diameters.
116    Just like regular OpenSCAD, you can create round objects by either specifying the diameter
117    or radius of the circle. This is done using the `CircleType` enum which is either 
118    `Diameter(d)` or `Radius(r)`.
119
120    ## Creating objects in loops
121    In most cases, the `scad!` macro should be good enoough to create objects, but one
122    case where it is not,  is when you want to create several objects in a loop and 
123    add them as children to a specific object. In this case, you have to use the 
124    `add_child` method of the `ScadObject`  struct manually
125
126    ```
127    # #[macro_use]
128    # extern crate scad;
129    # use scad::*;
130
131    # fn main() {
132        //Create the parent and make sure its mutable
133        let mut parent = scad!(Union);
134
135        for i in 0..3 {
136            parent.add_child(scad!(Cube(vec3(0., i as f32, 0.))));
137        }
138    # }
139    ```
140*/
141
142mod scad_element;
143mod scad_object;
144mod scad_file;
145mod scad_type;
146pub mod common_objects;
147
148#[macro_use]
149pub mod scad_macros;
150
151pub use scad_element::*;
152pub use scad_object::*;
153pub use scad_element::ScadElement::*;
154pub use scad_element::CircleType::*;
155pub use scad_macros::*;
156
157pub use scad_file::*;
158pub use scad_type::*;
159
160pub use common_objects::*;