Reusing code written by others is an excellent way to speed up our CAD design process. With OpenSCAD, there are numerous libraries of code that we can utilize to create new and exciting designs. In this chapter, we will create a desk drawer using the BOSL Standard Library. Afterward, we will re-use the code we wrote to create our own OpenSCAD library.
In this chapter, we will cover the following:
The following is required to complete this chapter:
The General libraries in OpenSCAD includes the BOSL, dotSCAD, NopSCADlib, and BOLTS libraries. Implementing these libraries allows us to add things such as threaded rods, modeled parts (parts that are not 3D-printed but are used in designs), and mathematically complex shapes. The following section includes a short breakdown of each of these libraries.
The Belfry OpenSCAD Library (BOSL) consists of operations to create shapes such as rounded boxes and threaded rods. Operations to enhance OpenSCAD's translate and rotate operations are also included in the BOSL.
In Figure 6.1, we can see a threaded rod created using the BOSL:
We will be exploring the BOSL in more detail in the upcoming Using the BOSL to design a desk drawer section.
The dotSCAD library aims to reduce mathematical complexity when using OpenSCAD. We can utilize dotSCAD to create complex shapes for our designs. In Figure 6.2, we can see a rose created in OpenSCAD using the dotSCAD library:
This rose can be modified and easily put into our designs, saving us the hassle of importing a rose as a 3D object.
The NopSCADlib library provides modeled parts for use in our OpenSCAD designs. These parts include things such as bearings, batteries, and parts for RepRap 3D printers that cannot be 3D-printed.
In Figure 6.3, we can see a hygrometer rendered in OpenSCAD using the NopSCADlib library:
This object was rendered using a single line of code and represents the standard mini hygrometer that can be purchased online at places such as Amazon and eBay.
Hygrometers and 3D Printing
Hygrometers measure ambient temperature and relative humidity and are useful tools for 3D printing. For hygroscopic filaments, such as nylon, it is important to keep the environment as dry as possible when storing and printing. Hygrometers placed with filaments in vacuum bags or in 3D printer enclosures allow us to measure the relative humidity and adjust the environment (such as the addition of silica packets).
Rendering non-3D-printable objects in OpenSCAD allows us to design around objects such as hygrometers. This saves us from having to measure the part in the real world and compensate for it in our OpenSCAD design.
BOLTS (not an acronym) is a free and open source library of standard parts that we can incorporate into our OpenSCAD designs. These parts consist mainly of standard nuts, bolts, pipes, and so on that we can use with our 3D-printed parts in our projects.
In Figure 6.4, we can see a pipe generated using the BOLTS library. Three parameters were used to create this pipe – the inside diameter (8 mm), the outside diameter (10 mm), and the length of the pipe (50 mm). The part was generated with the pipe(10, 8, 50) command:
Now that we have looked briefly at the OpenSCAD standard libraries, let's create a design using what we have learned. We will design a desk drawer by utilizing the BOSL. To create this design, we will download and install the library onto our computer. We will then use modules from the BOSL to create our desk drawer – a drawer with rails that rides on sliders bolted to the underside of a desk.
Let's get started.
As mentioned in the previous section, there are shapes such as rounded boxes that we can create using the BOSL. We will design our desk drawer using these shapes from the BOSL.
We will start by downloading and installing the library.
To download the BOSL, we do so from the OpenSCAD website. We then unzip, rename, and copy the contents into our OpenSCAD libraries folder.
To do so, follow these steps:
We have now installed the BOSL into our OpenSCAD installation. Let's start our design by creating the tray portion with a BOSL rounded box.
Before we create our design, we must import the libraries we require and set any variables we will use. To create the drawer tray of our desk drawer, we will start with a rounded box from the shapes.scad BOSL file:
use <BOSL/shapes.scad>
Observe that we do not need to put a semicolon at the end of the use line.
$fn=200;
width = 190;
length = 190;
height = 70;
rail_size=10;
hollow_factor = 0.95;
We already know that $fn sets the resolution of the design. The rest of the variables will be used to create the objects that will form our design.
cuboid([width,length,height], fillet=10);
We defined width, length, and height in our variable declarations. The fillet value sets the roundness of the cuboid.
module create_tray()
{
difference()
{
cuboid([width,length,height], fillet=10);
scale([hollow_factor,hollow_factor,hollow_
factor])
cuboid([width,length,height], fillet=10);
translate([0,0,height])
cube([width*2,length*2,height*2],
center=true);
}
}
create_tray();
There is quite a lot of code here, so let's go through it before we render. What we are essentially doing is taking the difference between our original cuboid and a scaled-down version of it. This scaled-down version is 5% smaller as the hollow_factor value is 0.95 (set with the initial variable declarations), and we use the scale operation to reduce a new version of the cuboid by this much. We then subtract a standard cube to cut the hollowed-out cuboid in half. We simply double the width, length, and height values on the standard cube to get a clean cut. We move the cube up by the value of height using the translate operation so that it will be above the z axis. We need to do this, as the cube is centered with all axes when it is created. Note that we move the cube up by the value of height and not height/2 as we usually do for objects that are centered on the z axis. This is due to the height*2 size of our cutaway cube.
Now that we have created the tray for our desk drawer, it is time to add side rails and sliders to our design. This will allow us to mount our tray under a desk or table.
Using include or use
We can import the shapes.scad file into our design by using an include statement instead of use. The difference between the two is in how shapes.scad is implemented. Both statements will bring in all the modules from shapes.scad. However, the include operation will execute any code that sits outside of any modules in shapes.scad, while the use operation will not. The difference between the two will become clearer when we create our own library in the Creating our own OpenSCAD library section.
We will now turn our attention to using rails and sliders from the BOSL. We use the sliders.scad file for both. We start by adding rails to our drawer.
The BOSL contains rails and sliders that we can use for our desk drawer. These parts give us the objects we need to allow our desk drawer to slide in and out from under our table or desk.
To add rails, follow these steps:
use <BOSL/sliders.scad>
//create_tray();
rail(l=length-20, w=rail_size, h=rail_size);
What we have done here is to create a rail that is the length value of our drawer minus 20 mm. We make it shorter to account for the round corners of the tray. We have already declared rail_size to be 10 in our variable declarations, and we use this variable to define the width (w) and height (h) values of our rail.
module create_rail()
{
translate([width/2,0,-(rail_size/2)])
rotate([0,90,0])
rail(l=length-20, w=rail_size, h=rail_size);
}
What we have done here is rotate the rail to a position that will make it useful. We then move it to the right by half the width value, as the tray is positioned in the center of our design. We move it down by half of its height (rail_size/2) value so that it will be below the z axis and line up with our tray.
create_tray();
create_rail();
create_tray();
create_rail();
mirror([1,0,0])create_rail();
The mirror operation does exactly what its name implies – it creates a mirror of an object. The parameters determine where the mirroring occurs based on x, y, and z values. In our case, we are mirroring in the x direction.
As we can see, the rails give our drawer something to mount inside a slider. Before we create the sliders for mounting the rails, we will add a handle to the drawer.
To create a handle, we will use cuboid from the BOSL and cut away a portion of it. We will position this handle on the front of the drawer. We will place the code to do this in a module.
To create the handle, follow these steps:
module create_handle(size)
{
translate([0,-length/2,-(size*1.5)])
difference()
{
difference()
{
cuboid([5*size,3*size,1.5*size],
fillet=2);
scale([0.8,0.8,2])
cuboid([5*size,3*size,1.5*size],
fillet=2);
}
translate([0,size*50,0])
cube([size*100,size*100,size*100],
center=true);
}
}
There is a lot of code here. Let's step through it before we move on to implementing it. If we start with the second difference() operation, we can see that we take the difference between a cuboid created to be 5 times the size parameter in the x direction, 3 times in the y direction, and 1.5 times in the z direction, with a version of the same cuboid but 80% of its size in the x and y directions and 200% in the z direction.
These multiplication values are arbitrary and were chosen for the shape that they create. With the first difference() operation, we simply cut our handle in half with a box that is much bigger and moved over to be on one side of the y axis. We then moved the whole shape in place with the first translate() operation, placing it in front of our tray.
create_tray();
create_rail();
mirror([1,0,0])create_rail();
create_handle(10);
With create_handle(10);, we are creating a handle with a starting value of 10. The result will be a handle that is 50 mm in the x direction, 30 mm in the y direction, and 15 mm in the z direction.
For reference, here is a picture of a drawer that has been 3D-printed and painted:
Now that we have completed the drawer portion of our desk drawer, it is now time to design the sliders that allow the drawers to slide in and out under the table.
As mentioned in the Adding rails to our drawer tray section, there are slider objects in the BOSL. We will create a slider and then move it into the correct position.
Let's get started:
module create_slider(offset)
{
base=20;
slider(l=length,h=rail_size,base=base,
wall=4,slop=offset);
}
What we are doing here is creating slider equal to the length value of the drawer with a base value of 20 mm. The offset value is used to create some space between the rail and the slider.
//create_tray();
//create_rail();
//mirror([1,0,0])create_rail();
//create_handle(10);
create_slider(0.4);
We are calling the create_slider() module with an offset value of 0.4. This value may be experimented with to provide a snug fit between the rail and the slider.
module create_slider(offset)
{
base=20;
translate([width/2+(rail_size+base),0,
-rail_size/2])
rotate([0,-90,0])
slider(l=length,h=rail_size,base=base,
wall=4,slop=offset);
}
To understand what we just did here, let's work from the bottom to the top. With this change, we rotate slider -90 degrees on the y axis. We then move it to the right on the x axis by a value that is equal to half the width value (as the drawer is centered) plus the size of the rail and slider base added together (width/2+(rail_size+base)). We then move the slider down so that it lines up with the rail (-rail_size/2).
create_tray();
create_rail();
mirror([1,0,0])create_rail();
create_handle(10);
create_slider(0.4);
mirror([1,0,0])create_slider(0.4);
Now that we have created the sliders for our desk drawer, there is one task that remains. We need to create screw holes on the sliders so that they may be mounted onto the bottom of our desk or table.
In the next section, we will do just that.
We will create a separate module to create the screw holes. We will then call that module from the create_slider() module. This will keep our code clean and also allow code re-use.
Let's get started:
module create_3mm_screw_hole()
{
union()
{
cylinder(d=3, h=500);
translate([0,0,-500])
cylinder(d=10, h=500);
}
}
//create_tray();
//create_rail();
//mirror([1,0,0])create_rail();
//create_handle(10);
//create_slider(0.4);
//mirror([1,0,0])create_slider(0.4);
create_3mm_screw_hole();
What we are doing here is simply creating two cylinders stacked together, one that is 3 mm in diameter and one that is 10 mm in diameter. The 3 mm hole is the actual hole our screw will go through; the 10 mm one is the countersink hole for the screw. We have made both cylinders extremely long to provide for clean cuts. The cylinders sit in the middle on the z axis.
module create_slider(offset)
{
base=20;
hole_inset=20;
difference()
{
translate([width/2+(rail_size+base),0,
-rail_size/2])
rotate([0,-90,0])
slider(l=length, h=rail_size,
base=base,wall=4, slop=offset);
translate([width/2+(rail_size+(base/2)),
(length/2)-hole_inset,-rail_size/2])
create_3mm_screw_hole();
translate([width/2+(rail_size+(base/2)),
-((length/2)-hole_inset),-rail_size/2])
create_3mm_screw_hole();
}
}
Before we render our design, let's go through the changes. Basically, what we are doing in the new create_slider() module is taking the difference between slider and a 3 mm screw hole. We have added a new variable called hole_inset, which is the value from the ends of the slider where we want to place our screw holes. In this case, we are putting our screw holes 20 mm from the ends. The translate() operation moves the holes to the base part of the slider, away from the side where the drawer will slide. The second translate() operation differs from the first by taking the negative value in the y direction to make a mirrored copy. The holes are then moved down in the z direction by half the rail_size value to countersink the screw hole.
create_tray();
create_rail();
mirror([1,0,0])create_rail();
create_handle(10);
create_slider(0.4);
mirror([1,0,0])create_slider(0.4);
We have now finished our design of the desk drawer. As we can see, we are able to easily leverage the OpenSCAD standard library to create new and interesting designs.
In the next section, we will look at OpenSCAD Single Topic libraries.
Now that we understand how OpenSCAD standard libraries can be utilized to improve our designs, let's look at what are called OpenSCAD Single Topic libraries. As their name implies, OpenSCAD Single Topic libraries are used for specific purposes, such as creating a threaded nut for a design. There are six libraries listed on the OpenSCAD website (http://openscad.org/libraries.html) under Single Topic. We will look at the four most relevant (for our purposes) libraries:
Let's start with the Round Anything library.
The motivation behind the Round Anything library is, as its name implies, to round parts. Standard OpenSCAD code lacks the functionality for rounding basic shapes. Installing this library provides a good tool to use in our designs.
For our example, however, we will look at the shell2d() operation, which ironically does not round a part. With shell2d(), we create a hollow outline of a 2D shape. We can then use the gridpattern() operation from Round Anything to create a grid inside the new shape.
In Figure 6.16, we can see the effect of the shell2D() operation on a 2D sketch. The image on the left is the shape we created in Chapter 4, Getting Started with OpenSCAD, for the PVC hook. Applying the shell2D() and gridpattern() operations on this shape creates what we see on the right side:
To create the shape on the right, follow these steps:
use <Round-Anything/roundAnythingExamples.scad>
shell2d(0, -5)
{
intersection()
{
translate([20,0])
circle(d=80);
translate([30,0])
square([60, 70], center=true);
}
gridpattern(iter=50);
}
In this code, we create square with one rounded side using the intersection() operation. We then wrap that inside the shell2d() operation with offset values of 0 and -5. This defines the thickness of the shell (negative numbers create the shell inward, and positive numbers outward). For these numbers, we will create a shell with an inside wall thickness of 5 mm. We then add gridpattern(iter=50); , which creates a pattern inside our shape.
//gridpattern(iter=50);
There is much more functionality to the Round Anything library than we have touched on. What is important to gain from this exercise is the power that this external library can bring to our designs.
We will now look at a library that will build enclosures for us.
With this library, we can easily create enclosures for our projects with a few lines of code. We can make enclosures with interlocking rims, snap-fit enclosures, and rounded corners.
For our example, we will create a simple hinged enclosure with a few lines of code. To create our hinged box, follow these steps:
include <MarksEnclosureHelper/hingebox_code.scad>
hingedbox( box_def );
hinge_points = [0.5];
hinge_len = 20;
What we have done here is define a standard hinged box enclosure. It may seem odd that we are simply setting variables without passing them into a module or operation, but take note of include at the top. This library relies heavily on code that is written outside of modules. If we were to replace include with use, the code will not work. The hinge_points variable defines where the hinges are located, with the 0.5 value putting them in the middle of the enclosure. The hinge_len variable defines the size of the hinge, which we set to 20.
A common task among makers with 3D printers is creating enclosures for various projects. Having a library that does this with ease is a great tool to have.
Now that we know how to create quick enclosures, let's turn our attention to creating screws and bolts that we can use in our designs.
The OpenSCAD threads.scad library is designed to be an efficient way to generate bolts, threaded rods, and nuts that we can use in our projects.
In our example, we will create a 25 mm M10 bolt with a couple of lines of code. Let's get started:
use <threads.scad>
MetricBolt(10, 25, tolerance=0.4);
This code couldn't be simpler. We pass in 10 for the diameter and 25 for the length. We can adjust tolerance if we are finding our 3D prints of this bolt too tight or too loose.
include <threads.scad>
MetricBolt(10, 20, tolerance=0.4);
Now that we can see there is an easy way to generate threaded nuts and bolts, let's turn our attention to a library that generates smooth basic objects for us.
This library provides common primitive shapes with additional parameters to smooth out the shape. As many of us know, it is not always easy to round off or smooth an edge of a common shape in OpenSCAD. Although this library is not vast, it does provide a few useful shapes that we can implement in our designs.
For our example, we will look at SmoothCylinder. To explore this, follow these steps:
use<smooth_prim.scad>
SmoothCylinder(10, 30, 5);
In the code, we are creating SmoothCylinder with a radius of 10 mm, a length of 30 mm, and a smoothing radius of 5 mm.
It is easy to see how we can use SmoothCylinder in our OpenSCAD designs and how easy it is to create one. For example, by cutting SmoothCylinder in half and hollowing it out, we can create a bell jar-style cover for a project.
Now that we have a deeper understanding of how to use external libraries, let's create one of our own. We will use the code we wrote to create the desk drawer in the Using the BOSL to design a desk drawer section.
One way to turn our desk drawer code into a library file is to add it to our OpenSCAD installation's libraries directory. We can open this location on our computer by clicking on File | Show Library Folder... in OpenSCAD.
Before we do that, we should take note of how we will be using this library. If we were to simply copy the code as we left it in the Using the BOSL to design a desk drawer section, we could see the whole drawer with the sliders generated. This would happen when using an include statement for importing:
include <desk_drawer.scad>
This is due to the non-module code at the end of the file that creates the drawer and the sliders we added in the Using the BOSL to design a desk drawer section. We will, however, be able to change the size of the drawer and sliders, as we will have access to the non-module variables declared at the beginning of the desk_drawer.scad library file. This may seem like the way we should approach creating our own OpenSCAD library file. However, it would make little sense when it comes to 3D printing, as our 3D file export (.stl, .3mf) would have both the drawer and the sliders together. This would prove difficult to 3D-print as separate parts.
Another solution is to bring our library file into our new file with the use statement:
use <desk_drawer.scad>
With this approach, we solve the issue of the drawer and sliders rendered together, but we do not have access to the variables that would allow us to change the size of the drawer. Also, we would expect the user of this library to know which modules to call to build the various components of the drawer, such as create_tray() and create_rail(), and the corresponding mirror operation for creating the opposite side rail. The drawer would always be the size set by the variables at the beginning of the file unless we changed the input parameters for the modules to accept values for length, width, and height. This would add extra complexity for anyone using this library.
The best solution is to modify our file and instruct our user to use our library like any other OpenSCAD library by using the include statement.
Let's do just that:
module create_drawer()
{
create_tray();
create_rail();
mirror([1,0,0])create_rail();
create_handle(10);
}
module create_sliders(offset=0.4)
{
create_slider(offset);
mirror([1,0,0])create_slider(offset);
}
module create_slider(offset=0.4)
{
base=20;
translate([width/2+(rail_size+base),0,
-rail_size/2])
rotate([0,-90,0])
slider(l=length,h=rail_size,base=base,
wall=4,slop=offset);
}
This new offset value makes the library a little easier to use for calls to create_slider(). We use create_slider() when we need to generate a single slider.
include <desk_drawer_lib.scad>
width=500;
create_drawer();
create_sliders();
With this code, we import our library, and then we set the width value to 500. We then create the drawer and the sliders.
By arranging our library code this way, it becomes easy to generate objects for 3D printing. For example, if we wanted to print a single slider, we could generate one with this code:
create_slider();
With our object stored as a .stl file, we can then proceed to load it into a slicer program, such as Cura, and prepare it for 3D printing.
Having our desk drawer code as an installed library means we can utilize it to generate desk drawers easily. This allows us to place such a component in larger designs – for example, a design of an entire workshop.
The ability to see our designs before construction is the power of OpenSCAD and CAD design in general. It limits any measurement mistakes and, thus, any post-construction modifications.
In this chapter, we introduced external libraries to our designs. We were able to use the BOSL to design a desk drawer that slides on sliders under our desk. We also explored many of the libraries available from the OpenSCAD website, noting the design inspirations and strengths of the libraries.
We were able to then take the code written for our desk drawer design and implement it as an OpenSCAD library. As we saw, doing this greatly simplifies future designs. It allows us to design something rather complex by breaking it down into separate components.
With this chapter, we come to the end of the second part of this book, Learning OpenSCAD, where we explored OpenSCAD from basic to more complex concepts. We will use this knowledge in the third part of this book, Projects, as we use OpenSCAD to design and then bring our designs to life through 3D printing.
3.142.248.104