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::*;