In fall 2023 I took a class on computational fabrication, using computer programming to design objects otherwise difficult or impossible to make. Common examples include patterns controlled or variated based on input parameters, and tools that provide user interface or backend calculation for fabrication challenges. Three different projects I completed in the class are featured here, with a table of contents to go directly to a project section.
In this assignment, I used Rhino and Grasshopper to parametrically design a piece of furniture and 3D printed it at a small scale. I made a chair design with a crinkly exterior texture by moving points outwards a random distance from a base circle. My complete grasshopper code is as follows, with two python blocks to generate the random points and interpolate a curve for the backrest.
Here are two chairs produced by this code, one with 50 exterior points and a 5mm maximum random displacement, and one with 200 points and 1mm maximum random displacement.
I printed a chair design with 50 points, and I am quite happy with the result. I am unsure on the quality of this chair if it were actually made at a large scale, but I gained a lot of experience with Rhino and Grasshopper with this project.
For this assignment I created a rudimentary slicer for 3D printing in Grasshopper. While the assignment only called for the slicer to be used on a basic cylinder, it should function on any shape with single perimeters in each layer. I went above and beyond with additional available time to also implement infill percentage, serpentine infill, and correct spacing between the infill and edge geometry. The complete grasshopper code is shown below, organized by subtask with input parameters positioned above as a bus.
Using a cylinder of 10 mm radius and 0.3 mm height as an example, the program first constructs the shape and initializes printer parameters.
The object is then intersected with a series of x-y planes based on the 3D printer layer height and bounding box domain to create the contours for each layer.
The contours are then optimized for 3D printing by subdividing them into 0.1 mm line segments and recombining the segments that don't deviate laterally by more than 0.1 mm. 0.1 mm was the minimum precision of the 3D printer we had, so smaller segments than this would not produce more precise results.
The optimized straight line segments appear as follows:
The next step is creating the infill. In the left blue group below, the bounding box of each slice's contour is used to generate a line in the y direction, and the x domain size is provided to the infill setup parameters group. In the bottom blue group, the y direction line is replicated into a linear array of lines based on the infill parameters, trimmed by the edge contours, and connected together. Several calculations for generating the infill lines, including the count based on infill percentage and edge contour spacing for trimming, are done in the top blue box. The edge and infill contours are then merged to the right of the green box.
The offset of the edge contours is based on an equation from the labeled source. The reason for this offset is because extrusion paths are squashed from cylindrical and must overlap slightly.
I also made the rectilinear infill follow a serpentine path, which minimizes travel time between infill lines. Every other infill line is first reversed in direction in a python script, and then the segments are connected together. If multiple layers are present in the print, it is important that infill lines connect only to the infill lines on the same layer, which is resolved by the Trim Tree component.
The line segments after infill is added appear as follows:
Here is an example with a cylinder ten times as tall:
Here is a 40mm radius cylinder at 10, 20, and 50 percent infill:
Lastly, The contour is exploded into individual line segments, fed into my python script that translates it into G-code, and exported as a txt file.
The main section of the python script is as follows. Each line segment can create 2 lines of Gcode, one for moving to the start of the line segment if not already there, and one for extruding along the line segment. The gcodeMove function handles the syntactical creation of G1 move commands. There are also calculations performed for the correct amount of filament to be extruded. Not shown here are the start and end blocks of Gcode that are prepended and appended to the list of G1 move commands.
The class was unfortunately unable to test any G-code on a 3D printer, but here is the resulting G-code shown in an online analyzer. I thoroughly enjoyed this assignment for the result created, which serves as a clear demonstration of understanding 3D printer operations.
I like to draw mazes on isometric dot paper, image and scan shown below, but these versions are sketched with rough lines and on a fragile medium. For this project, I built a tool to turn these drawn mazes into svg vector files that enable cleaner renderings and more durable laser cut versions of the designs. The final drawing tool has been optimized for efficient tracing and is written in Processing, a free and open source software.
I initially wanted to create a program that visually recognized the lines of the maze automatically. I made significant progress on my planned approach, aligning a grid to the imported drawing, using thresholds to isolate black and white pixels, and creating a mask for each segment type to isolate and test pixel sums within the mask. This is shown as follows, with the selected region, the mask, and the region after masking in the top left corner, but the diagonal mask shown fails to detect the diagonal line selected in the green box. My drawn lines were simply not precise enough for this approach, and detecting the shapes and intersections of lines not based on a grid is an open research challenge I would not have been able to fully solve in the available time.
An example of my final drawing program in use follows. The user first drags and drops an image onto the program window, and any line segments drawn in a previous session are saved in txt file that can also be dragged and dropped back into the program. The user then selects two points in the upper left and lower right of the maze to align it to a grid, which can also be realigned at any time. All lines and curves snap to this grid to achieve a perfectly aligned result.
The type of segment is selected with keyboard shortcuts, which optimized for efficient use with the left hand while the right hand controls the mouse. The curve is placed by clicking on the relevant grid points, a preview of the segment is shown after the first endpoint is selected, and the beginning of the next segment automatically starts at the end of the previous segment. Keyboard shortcuts are also available for deselecting a segment type, undoing the last segment, erasing all segments connected to a certain grid point, and saving the maze as an svg and png file.
I traced four mazes in total, shown below, and the program functioned satisfyingly well to do this efficiently.
I then laser cut the designs into acrylic, and added some gold custom cut stickers for the start and finish with a cutting machine.