OpenSCAD User Manual/CSG Modelling

boolean overview

2D examples
 union()       {square(10);circle(10);} // square or  circle
 difference()  {square(10);circle(10);} // square and not circle
 difference()  {circle(10);square(10);} // circle and not square
 intersection(){square(10);circle(10);} // square and circle
3D examples
 union()       {cube(12, center=true); sphere(8);} // cube or  sphere
 difference()  {cube(12, center=true); sphere(8);} // cube and not sphere
 difference()  {sphere(8); cube(12, center=true);} // sphere and not cube
 intersection(){cube(12, center=true); sphere(8);} // cube and sphere

union

Creates a union of all its child nodes. This is the sum of all children (logical or).
May be used with either 2D or 3D objects, but don't mix them.

 //Usage example:
 union() {
 	cylinder (h = 4, r=1, center = true, $fn=100);
 	rotate ([90,0,0]) cylinder (h = 4, r=0.9, center = true, $fn=100);
 }

Remark: union is implicit when not used. But it is mandatory, for example, in difference to group first child nodes into one.

Note: It is mandatory for all unions, explicit or implicit, that external faces to be merged not be coincident. Failure to follow this rule results in a design with undefined behavior, and can result in a render which is not manifold (with zero volume portions, or portions inside out), which typically leads to a warning and sometimes removal of a portion of the design from the rendered output. (This can also result in flickering effects during the preview.) This requirement is not a bug, but an intrinsic property of floating point comparisons and the fundamental inability to exactly represent irrational numbers such as those resulting from most rotations. As an example, this is an invalid OpenSCAD program, and will at least lead to a warning on most platforms:

 // Invalid!
 size = 10;
 rotation = 17;
 union() {
    rotate([rotation, 0, 0])
       cube(size);
    rotate([rotation, 0, 0])
       translate([0, 0, size])
       cube([2, 3, 4]);
 }

The solution is to always use a small value called an epsilon when merging adjacent faces like this to guarantee overlap. Note the 0.01 eps value used in TWO locations, so that the external result is equivalent to what was intended:

 // Correct!
 size = 10;
 rotation = 17;
 eps = 0.01;
 union() {
    rotate([rotation, 0, 0])
       cube(size);
    rotate([rotation, 0, 0])
       translate([0, 0, size-eps])
       cube([2, 3, 4+eps]);
 }

Difference Operator Module

This operator does nothing when given a single child:

difference() cube();

Having it operate on two or more children performs the logical And-Not operation by deleting the shapes following the first from it.

Intersection may be applied to 2D or 3D objects, but should be applied to objects of only one type. Mixing 2D and 3D child nodes will give indeterminate results, if any.

Usage example:
difference() {
	cylinder (h = 4, r=1, center = true, $fn=100);
	rotate ([90,0,0]) cylinder (h = 4, r=0.9, center = true, $fn=100);
}

Note: It is mandatory that surfaces that are to be removed by a difference operation have an overlap, and that the negative piece being removed extends fully outside of the volume it is removing that surface from. Failure to follow this rule can cause preview artifacts and can result in non-manifold render warnings or the removal of pieces from the render output. See the description above in union for why this is required and an example of how to do this by this using a small epsilon value.

Difference With Multiple Children

Note, in the second instance, the result of adding a union of the 1st and 2nd children.

// Usage example for difference of multiple children:
$fn=90;
difference(){
    cylinder(r=5,h=20,center=true);
    rotate([00,140,-45])
        color("LightBlue")
            cylinder(r=2,h=25,center=true);
    rotate([00,40,-50])
        cylinder(r=2,h=30,center=true);
    translate([0,0,-10])
        rotate([00,40,-50])
            cylinder(r=1.4,h=30,center=true);
}
   
// second instance with added union
translate([10,10,0]){
    difference(){
      union(){        // combine 1st and 2nd children
                                                cylinder(r=5,h=20,center=true);
        rotate([00,140,-45]) color("LightBlue") cylinder(r=2,h=25,center=true);
      }
      rotate([00,40,-50])                       cylinder(r=2,h=30,center=true);
      translate([0,0,-10])rotate([00,40,-50])   cylinder(r=1.4,h=30,center=true);
    }
}

Intersection Operator Module

Creates the intersection of its child nodes. This logical and operation creates an object that is the overlapping part of all the child nodes together

Intersection may be applied to 2D or 3D objects, but should be applied to objects of only one type. Mixing 2D and 3D child nodes will give indeterminate results, if any.

//Usage example:
intersection() {
	cylinder (h = 4, r=1, center = true, $fn=100);
	rotate ([90,0,0])
        cylinder (h = 4, r=0.9, center = true, $fn=100);
    }