A module in OpenSCAD is similar to a macro or function in other languages. Creating a module allows you to easily reuse code and to create parametric models. To define a module:
You can specify default values in your definition like this:
To use the module:
module Name_of_module(param1,param2,...){ //statements... }
You can specify default values in your definition like this:
module house(roof="flat", paint=[1,0,0]){
color(paint)
if(roof=="flat"){
translate([0,-1,0])
cube();
}else if( roof=="pitched"){
rotate([90,0,0])
linear_extrude(height=1)
polygon(points=[[0,0],[0,1],[0.5,1.5],[1,1],[1,0]],paths=[ [0,1,2,3,4] ]);
}else if(roof=="domical"){
translate([0,-1,0])
union(){
translate([0.5,0.5,1])
sphere(r=0.5,$fn=20);
cube();
}
}
}
To use the module:
house(); translate([1,0,0]) house("pitched", [0,1,0]);
Creating a Module
- Open OpenSCAD
- In the editor add code to define the name of a module. The module should be called join_two_points. This module will take the following parameters:
- x1
- y1
- z1
- x2
- y2
- z2
- diameter
- You will use the distance formula to create the value for a variable called length.
Inside the module, create a variable called length and set it to
sqrt( pow(x1 - x2, 2) + pow(y1 - y2, 2) + pow(z1 - z2, 2) );
- Tertiary syntax allows you to test a conditional and assign a value based on the evaluation in one line:
You want to determine if the difference between the y1 and y2 is not 0. If this condition is met than you want to set alpha to the inverse tangent (arctangent) of (z2 - z1) / (y2 - y1).
//if a is less than b then set the string to "hello" //if a is not less than b then set the string to "good bye" ((a<b) ? string="hello": string="good bye");
The arctangent is used to calculate the angles of a right triangle. It will return the angle of the given ratio.
To illustrate arctangent, start with a right triangle with sides a and b. The typical way to use the tangent function is to calculate the ratio of the two non-hypotenuse sides of a right triangle, such as a and b, from the angle (θ) between b and the hypotenuse. This is indicated as tan(θ) = b / a.
arctangent works in the opposite direction; you can use the ratio b / a to find the angle θ, such that θ = atan(b / a).
Create a variable named beta and if x2- x1 does not equal 0 than set beta to 90-atan( (z2 - z1) / (x2 - x1) ) otherwise set it to 90- 0.
- Create a variable named gamma and if x2- x1 does not equal 0 than
set gamma to atan( (y2 - y1) / (x2 - x1)
Otherwise
set gamma to ( (y2 - y1 >= 0) ? 90 : -90 ) ) + ( (x2 - x1 >= 0) ? 0 : -180 )
- To display values of variables, you use the keyword echo
echo(Length = length, Alpha = alpha, Beta = beta, Gamma = gamma);
- Call translate() and translate the object by
x1, y1, z1
- Call rotate() and rotate the object by
0, beta, gamma
- Create a cylinder where the height = length and radius = diameter/2
- To use the module you specify the starting x, y and z and the ending x, y and z:
join_two_points(0, 0, 0, 50, 0, 0, 5 ); // +X join_two_points( 50, 0, 0, 50, 50, 0, 5 ); // -X join_two_points( 50, 50, 0, 0, 50, 0, 5 ); // +Y join_two_points( 0, 50, 0, 0, 0, 0, 5 ); // -Y join_two_points( 0, 0, 0, -50, -50,0, 5 ); // -X -Y join_two_points( 0, 0, 0, 50, 50, 50, 5 ); // +XYZ
- Here is the module to add rounded corners:
module corner(x, y, z, diameter){ translate([x, y, z]) sphere( r = diameter/2 ); }
- This code:
produces this:
diameter=2; cubeHeight=10; width=50; length=50; innerWidth=20; innerLength=10; translate([-25,-25,-10]){ cube([width,length,cubeHeight]); for(z=[0:2]){ perimeter(width,length,cubeHeight+z*diameter,diameter); } translate([(width-innerWidth)/2,(length-innerLength)/2,0]){ for(z=[0:2]){ perimeter(innerWidth,innerLength,cubeHeight+z*diameter,diameter); } } }
- Complete the program by creating the module perimeter.
- View the model by pressing F5.
- Render and Compile by pressing F6. Then select Design>Export as STL
Using Variables
You could rewrite the module so that it would be parametric:module house(roof="flat", paint=[1,0,0], s=20){ color(paint) if(roof=="flat"){ translate([0,-s,0]) cube(s); }else if( roof=="pitched"){ rotate([90,0,0]) linear_extrude(height=s) polygon(points=[[0,0],[0,s],[s/2,3*s/2],[s,s],[s,0]],paths=[ [0,1,2,3,4] ]); }else if(roof=="domical"){ translate([0,-s,0]) union(){ translate([s/2,s/2,s]) sphere(r=s/2,$fn=20); cube(s); } } } house(); translate([40,0,0]) house("pitched"); translate([80,0,0]) house("domical",[0,1,1]); translate([0,40,0]) house(roof="pitched",paint=[0,0,1]); translate([20,20,0]) house(paint=[0,0,0],roof="pitched"); translate([60,40,0]) house(roof="domical"); translate([80,60,0]) house(paint=[0,.5,.2]);