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