Difference between revisions of "Workshops/OpenSCAD"

From LVL1
Jump to navigation Jump to search
Line 3: Line 3:
 
<pre>cube([10,20,30]);</pre>
 
<pre>cube([10,20,30]);</pre>
 
*[ ] refers to cartesian coordinates
 
*[ ] refers to cartesian coordinates
**if you're doing X,Y,Z use []
+
*if you're doing X,Y,Z use []
***for example:
+
*for example:
 
<pre>cylinder(h=10,r=10);</pre>
 
<pre>cylinder(h=10,r=10);</pre>
***h and r are not cartesian coordinates.  Do not use [ ] around them.
+
*h and r are not cartesian coordinates.  Do not use [ ] around them.
 
==Apply a transformation==
 
==Apply a transformation==
 
<pre>
 
<pre>

Revision as of 23:13, 21 March 2015

Hello World (a cube)

Make a solid

cube([10,20,30]);
  • [ ] refers to cartesian coordinates
  • if you're doing X,Y,Z use []
  • for example:
cylinder(h=10,r=10);
  • h and r are not cartesian coordinates. Do not use [ ] around them.

Apply a transformation

translate([0,-10,0])
cube([10,20,5]);
  • translate applies to cube because there is no ; at the end

Relate solids

difference() {
	translate([0,-10,0])
	cube([10,20,5]);
	cylinder(h=5,r=10);
}
  • Press F6 to compile the drawing

Done!

  • You made a drawing! Congrats, but you did it wrong. Lets improve thigns.

More Stuff

  • Take any of these, and repeat the same steps for Hello World
    • Solids:

http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Primitive_Solids

    • Transformations:

http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Transformations

    • Relations: (CSG Modeling)

http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/CSG_Modelling

    • Or, use this handy cheat sheet:

http://www.openscad.org/cheatsheet/

Variables

  • Pretend we want to change the height of this halfpipe
  • Change cube z to 10
difference() {
        translate([0,-10,0])
        cube([10,20,10]);
        cylinder(h=5,r=10);
}
  • The part is broken now! We can fix it my changing another number, but that's too much work. Let's try variables.
  • This sets the dimensions for the cube in variables:
max_x=10;
max_y=20;
max_z=5;
difference() {
        translate([0,-10,0])
        cube([max_x,max_y,max_z]);
        cylinder(h=5,r=10);
}
  • For the translate you can create static variales, or we can relate them to the other variables.
max_x=10;
max_y=20;
max_z=5;
difference() {
        translate([0,-max_y/2,0])
        cube([max_x,max_y,max_z]);
        cylinder(h=max_z,r=max_y/2);
}
  • Now everything for this shape is defined using these three variables. You can update any one and the whole part updates.

More variables

  • This part is not very practical to print. Lets add some thickness.
max_x=10;
max_y=20;
max_z=10;
circle_r=8;
difference() {
        translate([0,-max_y/2,0])
        cube([max_x,max_y,max_z]);
        cylinder(h=max_z,r=circle_r);
}
  • Now the part has some thickness, but this doesn't mean the drawing is done. We can re-arrange the variables to make it a more flexible drawing.
  • Pretend that this is half of a pipe clamp. Updating this drawing will not work very well.
max_x=10;
max_y=20;
max_z=10;
circle_r=11;
difference() {
        translate([0,-max_y/2,0])
        cube([max_x,max_y,max_z]);
        cylinder(h=max_z,r=circle_r);
}
  • Now it's broken.
  • Write more here.
  • First off, nobody measures pipes by their radius. Lets make this easier to plug in the pipe diameter:
max_x=10;
max_y=20;
max_z=10;
circle_d=16;
circle_r=circle_d/2;
difference() {
        translate([0,-max_y/2,0])
        cube([max_x,max_y,max_z]);
        cylinder(h=max_z,r=circle_r);
}

  • Now lets adjust the drawing so it always has walls:
circle_d=16;
circle_r=circle_d/2;
wall=3;

max_y=wall*2+circle_d;
max_x=wall+circle_r;
max_z=10;
difference() {
        translate([0,-max_y/2,0])
        cube([max_x,max_y,max_z]);
        cylinder(h=max_z,r=circle_r);
}
  • Consider other possibilities
    • Circle size not important but max size and wall thickness is
    • Circle size not important but ratio between circle and size is
  • When drawing a part ask yourself these questions:
    • When I make this part, which dimensions could make this a failure?
      • Example: the ring won't fit my finger. Base your other dimensions off the inside diameter of the ring.

Nitty Gritty Details

  • These are some things to know about the OpenSCAD language.

Stacking translates

  • Translates can be stacked on top of each other
max_d=20;
max_r=max_d/2;
max_z=5;
cutaway_d=max_z/2;
cube_w=cutaway_d*2;
angle=45;

difference() {
        cylinder(h=max_z,r=max_r);
        translate([0,-max_d/2,cutaway_d])
        rotate([0,-angle,0])
        cube([cube_w,max_d,cube_w]);
}
  • Sometimes it can be easier to do many translates instead of math:
  • This needs more explination...
max_d=20;
max_r=max_d/2;
max_z=5;
cutaway_d=max_z/2;
cube_w=cutaway_d*2;
angle=45;
tilt=10;

difference() {
        cylinder(h=max_z,r=max_r);

        translate([0,0,cutaway_d])
        rotate([tilt,0,0])
        translate([0,-max_d/2,0])
        rotate([0,-angle,0])
        cube([cube_w,max_d,cube_w]);
}

Curly Brackets

  • Curly brackets can be used to group objects together to apply transformations to multiple things at once.
  • In this example curly brackets are used to so that a bolt hole and the bolt head can be moved as one unit.
max_x=40;
max_y=max_x;
max_z=5;
bolt_d=3;
bolt_r=bolt_d/2;
head_h=2;
head_d=6;
head_r=head_d/2;

difference() {
        cube([max_x,max_y,max_z]);
        translate([max_x/2,max_x/2,0]) {
                cylinder(h=max_z,r=bolt_r);
                translate([0,0,max_z-head_h])
                cylinder(h=head_h,r=head_r);
        }
}

Modules

  • If we wanted to add another bolt hole to this plate we could copy the three lines and paste them elsewhere. However, if the bolt design changed we would have to update two places.
  • Place the bolt hole in a module and then call it wherever you want.
max_x=40;
max_y=max_x;
max_z=5;
bolt_d=3;
bolt_r=bolt_d/2;
head_h=2;
head_d=6;
head_r=head_d/2;

module bolt_hole() {
        cylinder(h=max_z,r=bolt_r); 
        translate([0,0,max_z-head_h])
        cylinder(h=head_h,r=head_r);
}

difference() {
        cube([max_x,max_y,max_z]);
        translate([max_x/2,max_x/2,0]) 
        bolt_hole();
        translate([10,10,0])
        bolt_hole();
        translate([8,32,0])
        bolt_hole();
        translate([22,29,0])
        bolt_hole();
}
  • Variables can also be passed to make different sized holes
$fn=45;
max_x=40;
max_y=max_x;
max_z=5;

module bolt_hole(bolt_d) {
        bolt_r=bolt_d/2;
        head_h=2;
        head_d=bolt_d*2;
        head_r=head_d/2;

        cylinder(h=max_z,r=bolt_r); 
        translate([0,0,max_z-head_h])
        cylinder(h=head_h,r=head_r);
}

difference() {
        cube([max_x,max_y,max_z]);
        translate([max_x/2,max_x/2,0]) 
        bolt_hole(3);
        translate([10,10,0])
        bolt_hole(7);
        translate([8,32,0])
        bolt_hole(4);
        translate([22,29,0])
        bolt_hole(2);
}

Exercise

  • How would you make a bolt plate with a hole in each corner?
  • There are many ways to do it:
max_z=5;
edge=7;
m4=3;

module bolt_hole(bolt_d) {

        bolt_r=bolt_d/2;
        head_h=2;
        head_d=bolt_d*2;
        head_r=head_d/2;

        cylinder(h=max_z,r=bolt_r); 
        translate([0,0,max_z-head_h])
        cylinder(h=head_h,r=head_r);
}

difference() {
        cube([max_x,max_y,max_z]);

        translate([edge,edge,0])  
        bolt_hole(m4);
        translate([edge,max_x-edge,0])
        bolt_hole(m4);
        translate([max_x-edge,edge,0])
        bolt_hole(m4);
        translate([max_x-edge,max_x-edge,0])
        bolt_hole(m4);
}
$fn=45;
max_x=40;
max_y=max_x;
max_z=5;
edge=7;
m4=3;

module bolt_hole(bolt_d) {

        bolt_r=bolt_d/2;
        head_h=2;
        head_d=bolt_d*2;
        head_r=head_d/2;

        cylinder(h=max_z,r=bolt_r);
        translate([0,0,max_z-head_h])
        cylinder(h=head_h,r=head_r);
}

module square(size, bolt) {
        translate([0,0,0])
        bolt_hole(bolt);
        translate([0,size,0])
        bolt_hole(bolt);
        translate([size,0,0])
        bolt_hole(bolt);
        translate([size,size,0])
        bolt_hole(bolt);
}

difference() {
        cube([max_x,max_y,max_z]);
        translate([edge,edge,0])
        square(max_x-edge*2,m4);
}
$fn=45;
max_x=40;
max_y=max_x;
max_z=5;
edge=7;
m4=3;

module bolt_hole(bolt_d) {

        bolt_r=bolt_d/2;
        head_h=2;
        head_d=bolt_d*2;
        head_r=head_d/2;

        cylinder(h=max_z,r=bolt_r);
        translate([0,0,max_z-head_h])
        cylinder(h=head_h,r=head_r);
}

difference() {
        translate([0,0,max_z/2])
        cube([max_x,max_y,max_z],center=true);

        translate([max_x/2-edge,max_x/2-edge,0])
        bolt_hole(m4);

        rotate([0,0,90])
        translate([max_x/2-edge,max_x/2-edge,0])
        bolt_hole(m4);

        rotate([0,0,180])
        translate([max_x/2-edge,max_x/2-edge,0])
        bolt_hole(m4);

        rotate([0,0,270])
        translate([max_x/2-edge,max_x/2-edge,0])
        bolt_hole(m4);
}

For loops

  • That last example can be greatly improved with a for loop:
$fn=45;
max_x=40;
max_y=max_x;
max_z=5;
edge=7;
m4=3;
holes=4;


module bolt_hole(bolt_d) {

        bolt_r=bolt_d/2;
        head_h=2;
        head_d=bolt_d*2;
        head_r=head_d/2;

        cylinder(h=max_z,r=bolt_r);
        translate([0,0,max_z-head_h])
        cylinder(h=head_h,r=head_r);
}

difference() {
        translate([0,0,max_z/2])
        cube([max_x,max_y,max_z],center=true);

        for (i = [1 : holes]) {
                rotate([0,0,360/holes*i])
                translate([max_x/2-edge,max_x/2-edge,0])
                bolt_hole(m4);
        }
}

Nesting Relations

bike_od=37.4;
bike_or=bike_od/2;
bike_h=3.25;
base_to_top=3.4;
axle_od=27.1;
axle_or=axle_od/2;
base_od=60;
base_or=base_od/2;
extend_h=3;


bottom_h=bike_h+base_to_top;
top_h=extend_h+bottom_h;

bottom_hole_h=bike_h;
top_hole_h=top_h;

bottom_r=base_or;
top_r=bike_or;

bottom_hole_r=bike_or;
top_hole_r=axle_or;

$fn=90;

difference() {
        union() {
                cylinder(h=bottom_h,r=bottom_r);
                cylinder(h=top_h,r=top_r);
        }
        cylinder(h=bottom_hole_h,r=bottom_hole_r);
        cylinder(h=top_hole_h,r=top_hole_r);
}

Pad

  • The models look a little rough without a render. This can be cleaned up by extending differences past the surface edge.
bike_od=37.4;
bike_or=bike_od/2;
bike_h=3.25;
base_to_top=3.4;
axle_od=27.1;
axle_or=axle_od/2;
base_od=60;
base_or=base_od/2;
extend_h=3;

pad=0.1;

bottom_h=bike_h+base_to_top;
top_h=extend_h+bottom_h;

bottom_hole_h=bike_h;
top_hole_h=top_h;

bottom_r=base_or;
top_r=bike_or;

bottom_hole_r=bike_or;
top_hole_r=axle_or;

$fn=90;

difference() {
        union() {
                cylinder(h=bottom_h,r=bottom_r);
                cylinder(h=top_h,r=top_r);
        }
        translate([0,0,-pad])
        cylinder(h=bottom_hole_h+pad,r=bottom_hole_r);
        cylinder(h=top_hole_h+pad,r=top_hole_r);
}

More Modules

  • Show origional washer

Misc

  • $fn=45;
  • Controlls how many points are in a circle
  • For example, $fn=3 will make triangles and $fn=4 will make squares. For prints I usually use $fn=120 and $fn=45 for writing code since it compiles faster.

Copying others work!

Using external libs

Thingiverse

  • openscad scripts
  • Customizer
    • Measuring Cup example
    • WALLY