2.6. Designing with OpenSCAD for 3D printing
OpenSCAD is ideal for quickly generating 3d-printable models. Unlike WYSIWYG CAD software, OpenSCAD generates prints programatically. This allows easy design and adjustment of prints based on repetitive patterns using parametric settings.
Note
These notes are based on my experiences with the Prusa i3 Mk3 and Artillery/Evnovo Sidewinder X1 printers. If you are using a different printer, please verify the hardware details are similar.
OpenSCAD is used extensively in the Thingiverse customizer.
These notes are meant to give a taste of OpenSCAD’s capabilities. Please refer to the OpenSCAD online user manual for more details.
Todo
OpenSCAD content
Test parts
Parametric prints
2.6.1. The OpenSCAD user interface
2.6.2. Programming in OpenSCAD
As you adjust the code using OpenSCAD’s programming language, a preview of the resulting model is shown in the view window.
If you adjust parameters or code, pressing the preview button ([F5]) will update the display to show the changes.
2.6.3. Downloadable parametric test prints
2.6.3.1. Bed leveling test
This model is a parametric bed leveling test to be used in conjunction with the Live-Z calibration procedure. It prints a pattern of rectangular shapes in a grid around the print bed, connected by thin lines for easy removal.
Here’s the source code:
1$fn = 90;
2
3t_bed_width = 250;
4t_bed_depth = 210;
5t_bed_border = 8;
6t_shape_xcount = 3;
7t_shape_ycount = 3;
8t_shape_xsize = 25;
9t_shape_ysize = 25;
10t_line_width = 1.6;
11t_thickness = 0.2;
12t_print_width = t_bed_width - t_shape_xsize - (2*t_bed_border);
13t_print_depth = t_bed_depth - t_shape_ysize - (2*t_bed_border);
14
15// Bed size
16//%square([t_bed_width, t_bed_depth]);
17
18// Grid area
19translate([t_bed_width/2,t_bed_depth/2]){
20 %square([t_print_width,t_print_depth], true);
21}
22
23// Print area
24translate([t_bed_width/2,t_bed_depth/2]){
25 %square([t_bed_width-(2*t_bed_border),t_bed_depth-(2*t_bed_border)], true);
26}
27
28linear_extrude(height = t_thickness) {
29 // shift everything to center in print area
30 translate([(t_shape_xsize/2)+t_bed_border,(t_shape_ysize/2)+t_bed_border,0]){
31 // intervals between printed shapes
32 t_increment_x = t_print_width / (t_shape_xcount-1);
33 t_increment_y = t_print_depth / (t_shape_ycount-1);
34 t_center_x = 0;
35 t_center_y = 0;
36
37 // draw grid
38 // draw horizontal lines along X axis
39 for(t_curr_x = [0:t_shape_xcount-1]){
40 translate([t_center_x, t_print_depth/2, 0]){
41 square([t_line_width,t_print_depth], true);
42 }
43 t_center_x = t_curr_x * t_increment_x;
44 }
45 // draw vertical lines along Y axis
46 for(t_curr_y = [0:t_shape_ycount-1]){
47 translate([t_print_width/2, t_center_y, 0]){
48 square([t_print_width, t_line_width], true);
49 }
50 t_center_y = t_curr_y * t_increment_y;
51 }
52
53 // draw shapes
54 t_center_x = 0;
55 for(t_curr_x = [0:t_shape_xcount-1]){
56 t_center_y = 0;
57 for(t_curr_y = [0:t_shape_ycount-1]){
58 translate([t_center_x,t_center_y]){
59 square([t_shape_xsize,t_shape_ysize],true);
60 }
61 t_center_y = t_curr_y * t_increment_y;
62 }
63 t_center_x = t_curr_x * t_increment_x;
64 }
65 }
66}
2.6.3.2. Test tower
This model is a parametric test tower. It generates a multi-level tower of user-specified dimensions with a divider and label at each level. You can see it in action on the |PS| modifiers page.
Here’s the source code:
1$fn = 90;
2
3t_levels = 7; // total number of levels to print
4t_start_label = 800; // starting numeric label
5t_label = t_start_label; // current level numeric label
6t_increment = 100; // increment for text labels on each layer
7t_baseheight = 1; // height of base and spacer levels in mm
8t_wallheight = 10; // combined height of wall on each layer
9t_width = 30; // tower width
10t_depth = 25; // tower depth
11t_wallthickness = 1.67; // wall thickness - min. 1.5mm for surface quality & z-seam alignment
12t_font = "Open Sans:style=ExtraBold";
13t_font_size = t_wallheight*0.6;
14t_font_depth = 0.4; // depth of text extrusions
15t_solid = true;
16t_name = "v20190403";
17t_model = "Generic";
18t_text_append = "";
19
20module outer_shell() {
21 // outer shell
22 square([t_width,t_depth], true);
23}
24
25module inner_shell() {
26 // inner shell is wallthickness thinner
27 square([t_width-t_wallthickness,t_depth-t_wallthickness], true);
28}
29
30module spacer_shell() {
31 // spacer shell is wallthickness thicker
32 square([t_width+t_font_depth,t_depth+t_font_depth], true);
33
34}
35
36module print_base(){
37 // solid base
38 color("goldenrod") {
39 linear_extrude(height = t_baseheight) {
40 //spacer_shell();
41 square([t_width+10,t_depth+10], true);
42 }
43 }
44}
45
46module print_spacer(curr_height, fill){
47 // elevate to current height
48 translate([0,0,curr_height]){
49 // spacer layer
50 color("gray") {
51 linear_extrude(height = t_baseheight) {
52 if( fill ) {
53 spacer_shell();
54 } else {
55 difference() {
56 spacer_shell();
57 inner_shell();
58 }
59 }
60 }
61 }
62 }
63}
64
65module print_level(curr_height, fill) {
66 // elevate to current height
67 color("lightblue") {
68 translate([0,0,curr_height]){
69 linear_extrude(height = t_wallheight) {
70 if( fill ) {
71 outer_shell();
72 } else {
73 difference() {
74 outer_shell();
75 inner_shell();
76 }
77 }
78 }
79 }
80 }
81}
82
83module print_text(curr_height,level_text) {
84 // text
85 translate([0,-t_depth/2,curr_height]){
86 color("wheat"){
87 // rotate text upright
88 rotate([90, 0, 0]) {
89 // extrude text
90 linear_extrude(height = (t_font_depth)) {
91 translate([0,t_wallheight/2,0]){
92 text(level_text,t_font_size,t_font,valign="center",halign="center");
93 }
94 }
95 }
96 }
97 }
98}
99
100// Generate test tower
101// print solid base
102print_base();
103for(t_level = [0:t_levels-1]){
104 // generate levels
105 if( t_level == 0 ) {
106 // allow for alternate text on 1st (0th) layer
107 print_level(t_level, t_solid);
108 print_text(t_level,str(t_label,t_text_append));
109
110 } else {
111 // generate succeeding layers
112 print_spacer(t_level*t_wallheight, t_solid);
113 print_level(t_level*t_wallheight, t_solid);
114 print_text(t_level*t_wallheight,str(t_label,t_text_append));
115 }
116 // update printed label for next layer
117 t_label = t_label + (t_level * t_increment);
118}
119
120color("red") {
121 // print final spacer layer at top of tower
122 if(t_solid) {
123 difference() {
124 print_spacer(t_levels*t_wallheight, t_solid);
125 translate([0,0,((t_levels*t_wallheight)+t_baseheight)-t_font_depth]){
126 linear_extrude(height = (t_font_depth+1)) {
127 text(t_name,t_font_size*.5,t_font,valign="center",halign="center");
128 }
129 }
130 }
131 } else {
132 print_spacer(t_levels*t_wallheight, t_solid);
133 }
134}
Contact and feedback
You can find me on the Prusa support forums or Reddit where I lurk in many of the 3D printing-related subreddits. I occasionally drop into the Official Prusa 3D discord server where I can be reached as bobstro (bobstro#9830). You can email me directly at projects@ttlexceeded.com.
Last modified Apr 03, 2021. Last build on Oct 22, 2021.