Week 05 – 3D Scanning and Printing
Han Ferik
Weekly Assignments:
Check Out Our Group Assignment
Group assignment:
Test the design rules for your 3D printer(s)
Document your work on the group work page and reflect on your individual page what you learned about characteristics of your printer(s)
Individual assignment:
Document your work on the group work page and reflect on your individual page what you learned about characteristics of your printer(s)
3D scan an object (and optionally print it)
3D Printing Initial Steps
Choosing The Right Environment
When preparing this assignment, I first looked into the common software workflow used in 3D printing. Additive manufacturing typically follows three main stages: modeling the object, slicing it into printable layers, and then sending the G-code to the printer. Because my goal is to produce small functional parts that demonstrate the unique advantages of additive manufacturing, I focused primarily on parametric CAD tools rather than artistic mesh modelers.
In my research, I found that parametric programs such as:
- Fusion 360,
- SolidWorks,
- and OpenSCAD
They are generally preferred for mechanical and print-in-place designs. These tools allow precise control over dimensions, tolerances, and relationships between parts, which is critical when designing moving components that must print successfully in one piece. Mesh-based software like Blender can be useful for organic shapes, but it is less suitable when tight mechanical clearances are required. After modeling, slicer software such as Cura, PrusaSlicer, or Bambu Studio is used to generate the machine instructions for the printer.
What Will I Build
For this project, I decided to produce nested moving cubes. Because the geometries and requirements of this design is quite different than before, I intentionally chose a different modeling tool for the cubes: OpenSCAD. The reason for this is, not every environment is perfect, but they might have the tools that will help our work to thrive more when compared to other environment
Environment for Nested Moving Cubes
For the nested moving cubes, I will be using OpenSCAD. I chose OpenSCAD because the design is highly parametric and concentric, and it requires very consistent clearances between each cube so the parts do not fuse during printing. Since OpenSCAD is code-based, I can define the clearance and wall thickness as variables and easily adjust them if needed. This makes the model highly reproducible and well suited for demonstrating print-in-place design principles. I also found that the repetitive nature of nested cubes aligns very naturally with OpenSCAD’s mathematical modeling approach.
Nested Moving Cubes
Setup Process
Now that I have identified the software environments, I can outline what I plan to do for the nested moving cubes and how I will approach the design so that the print succeeds functionally.
The goal of this model is to create a print-in-place mechanism consisting of multiple cubes nested inside one another, each able to move freely after printing. Simply placing one cube inside another is not sufficient, because without a proper design strategy the inner cube would either fuse to the outer cube during printing or fall out entirely if openings are too large. Therefore, the core design principle I will follow is controlled clearance combined with geometric containment.
In OpenSCAD, I will construct the model using parametric variables that define the outer cube size, wall thickness, and the clearance gap between moving parts. The primary tools I will rely on are basic constructive solid geometry operations such as cube(), difference(), and translate(). The outer cube will be created first and then hollowed using a subtraction operation to form a cavity. Inside this cavity, I will generate progressively smaller cubes, each offset inward by a uniform clearance value. This clearance is critical; it must be large enough to prevent fusion during printing but small enough to maintain proper containment.
To ensure the inner cubes remain trapped while still movable, I will also incorporate window openings on the faces of the outer cube. These openings will be smaller than the inner cube dimensions so that the parts cannot escape after printing. This is an important print-in-place design rule: the geometry must simultaneously allow printability, motion, and permanent capture. By keeping all key dimensions parametric in OpenSCAD, I will be able to quickly tune the gap value if my printer tolerances require adjustment.
Before starting the modeling work, I need to install and configure OpenSCAD.
To download OpenSCAD, I will go to the official website at openscad.org and download the version appropriate for my operating system. After running the installer and launching the program, I expect to see the script editor on the left and the 3D preview window on the right. No special plugins are required for this project.

For initial setup, I will make sure that the units are treated consistently in millimeters (OpenSCAD is unitless but I will design in mm convention). I will also familiarize myself with the two key preview commands: F5 for fast preview and F6 for full render. This distinction is important because boolean operations such as difference() only fully resolve during rendering. When the model is complete, I will export the geometry using File → Export → Export as STL, which will then be ready for slicing.
1. First, get familiar with the interface.
After you initialize your download process and finish downloading. You will have OpenSCAD as an application on your computer. Later when you open that application, you will come to an interface like below.

Here you will come at three different options, where you can select “New” to open a new OpenSCAD file. It will look like one below.

When OpenSCAD the file opens, you will see three main areas: the code editor on the left, the 3D preview window on the right, and the console at the bottom. Since OpenSCAD is code-driven, everything you model will begin in the editor. I usually start by resizing the window panels so I can clearly see both the code and the preview.
2. Second, verify the basic workflow (this is important).
Before jumping into the nested cubes, I like to confirm that preview and render are working correctly.
In a new file, type:
cube(20);
Then press F5 for preview. You should see a simple cube appear.
Next press F6 for full render. The cube should become solid and clean.

This quick check confirms your OpenSCAD installation is functioning properly.
3. Third, set up your working habits.
OpenSCAD does not use explicit units, but I will design in millimeters because slicers expect STL files in mm. From this point forward, every number I write will assume millimeters.
I also recommend saving your project immediately with a clear name such as:
nested_cubes_v1.scad
OpenSCAD does not auto-save, so saving early is good practice.
4. Fourth, adjust preview quality (optional but helpful).
For smoother curves later, I usually add these lines at the top of my file:
$fn = 64;

This controls resolution for curved objects. It will not affect cubes much, but it is good habit and will help in future projects.
5. Fifth, confirm navigation controls.
In the preview window, test:
Middle mouse drag → rotate
Shift + middle mouse → pan
Scroll wheel → zoom
Being comfortable with navigation will make debugging much easier once multiple cubes appear.
Finally, you are ready to begin the actual design.
The next step will be to define our key parameters (outer size, wall thickness, clearance, number of cubes) and start building the parametric nested cube structure.
Designing Process
We will construct a fully parametric, print-in-place nested cube system. The strategy is to define global parameters first, then generate each cube with proper clearances so nothing fuses during printing while still keeping the inner cubes trapped.
Just like we did before, open a new OpenSCAD file and start with the parameter block below.
// ===== GLOBAL PARAMETERS =====
outer_size = 30; // overall size of outer cube
wall = 2; // wall thickness
clearance = 0.4; // gap between moving parts (adjust per printer)
num_cubes = 3; // total nested cubes
$fn = 64;

These variables control the entire model. Later, if your printer is tight or loose, you will only change the clearance value and everything updates automatically.
Step 1 — Create a hollow cube module
We first define a reusable hollow cube. This keeps the code clean and scalable.
Add this below your parameters:
module hollow_cube(size, wall_thickness) {
difference() {
cube(size, center=true);
cube(size - 2*wall_thickness, center=true);
}
}

This creates a cube shell by subtracting a smaller cube from a larger one.
Press F5 — nothing appears yet (this is normal because we haven’t called the module).
Step 2 — Generate nested cubes
Now we will build the parametric nesting logic. Each inner cube must be smaller by:
wall thickness + clearance on both sides.
Add this main loop:
for (i = [0 : num_cubes - 1]) {
size_i = outer_size
- 2*i*(wall + clearance);
wall_i = (i == num_cubes - 1) ? 0 : wall;
if (size_i > 0) {
if (wall_i > 0)
hollow_cube(size_i, wall_i);
else
cube(size_i, center=true);
}
}
Now press F5.
You should see multiple cubes nested concentrically.

Step 3 — Add containment windows (VERY important)
Right now the cubes are trapped, but visually it’s not obvious and the assignment usually expects visible internal geometry. We will cut windows into the outer cube.
Add this module above the loop:
module outer_with_windows(size, wall_thickness) {
difference() {
hollow_cube(size, wall_thickness);
// window size (must be smaller than inner cube!)
win = size * 0.4;
// X windows
for (axis = [[1,0,0], [0,1,0], [0,0,1]]) {
rotate(a=axis==[1,0,0]? [0,90,0] :
axis==[0,1,0]? [90,0,0] :
[0,0,0])
cube([win, win, size*2], center=true);
}
}
}

Step 4 — Replace outer cube with windowed version
In your loop, replace the hollow cube call with this improved logic:
Find this part:
if (wall_i > 0)
hollow_cube(size_i, wall_i);
else
cube(size_i, center=true);
Replace with:
if (i == 0)
outer_with_windows(size_i, wall_i);
else if (wall_i > 0)
hollow_cube(size_i, wall_i);
else
cube(size_i, center=true);
Step 5 — Preview and render
Now:
Press F5 → quick preview
Press F6 → full render (important!)

Right now the cubes are geometrically separated, but they are not obviously free to move, and depending on the gaps they may still fuse. To make this a proper print-in-place moving mechanism, we need to do two things:
Guarantee uniform clearance on all faces
Prevent large flat surfaces from sticking
I also want to you guys to understand the motion of the cube inside, so I will also:
- Make the motion visually clear
The most reliable fix is to suspend each inner cube using small corner clearances and reduce face contact area. We will also slightly improve the sizing math so motion is guaranteed.
Let’s upgrade your model.
Step A — We will replace our main loop with this improved version
We will keep our parameter block and modules same for this step.
Step B — We will add anti-fusion corner chamfers (IMPORTANT)
Large parallel faces sometimes fuse on FDM printers. We fix this by slightly trimming inner cube corners.
This very slightly rounds edges and reduces sticking risk.
Step C — We will use safe cube for the innermost part
Step D — Increase visual motion (Optional but recommended. I will do it for you guys to understand my intention.)
To make movement obvious, I will slightly rotate inner cubes.
Inside the loop, we will wrap inner cubes with a rotate.
After this, the cubes will appear clearly independent.
Replace your entire code with this version
// ===== GLOBAL PARAMETERS =====
outer_size = 30; // overall size of outer cube
wall = 2; // wall thickness
clearance = 0.4; // gap between moving parts
num_cubes = 3; // total nested cubes
$fn = 64;
// ===== SAFE INNER CUBE (anti-fusion) =====
module safe_cube(size) {
minkowski() {
cube(size - 0.6, center=true);
sphere(0.3);
}
}
// ===== HOLLOW CUBE =====
module hollow_cube(size, wall_thickness) {
difference() {
cube(size, center=true);
cube(size - 2*wall_thickness, center=true);
}
}
// ===== OUTER CUBE WITH WINDOWS =====
module outer_with_windows(size, wall_thickness) {
difference() {
hollow_cube(size, wall_thickness);
win = size * 0.4;
for (axis = [[1,0,0], [0,1,0], [0,0,1]]) {
rotate(
a = axis==[1,0,0] ? [0,90,0] :
axis==[0,1,0] ? [90,0,0] :
[0,0,0]
)
cube([win, win, size*2], center=true);
}
}
}
// ===== MAIN GENERATION LOOP =====
for (i = [0 : num_cubes - 1]) {
size_i = outer_size - 2*i*(wall + clearance);
if (size_i > 0) {
// Outer cube
if (i == 0) {
outer_with_windows(size_i, wall);
}
// Middle hollow cubes (rotated for visibility)
else if (i < num_cubes - 1) {
rotate([0,0,15*i])
hollow_cube(size_i, wall);
}
// Innermost cube (rounded + rotated)
else {
rotate([0,0,15*i])
safe_cube(size_i - clearance);
}
}
}

I don’t know if its visible, but still to show, the inside cube is empty.

Add an inner shrink parameter
Since I would like the cube to be smaller, I added a shrink parameter.
At the top with your globals, add:
inner_scale = 0.75; // makes the smallest cube smaller (0.6–0.9 is good)
Modify ONLY the innermost cube line
Find this part in your loop:
safe_cube(size_i - clearance);
Replace it with:
safe_cube((size_i - clearance) * inner_scale);
Remove the rotation
For reliable print-in-place nested cubes, we should NOT rotate the cubes.
- because of its accidental touching
I only rotated the inner cube in order to show you guys the way it moves, therefore we can now remove it. So, keep all your modules exactly as they are. Just replace your MAIN GENERATION LOOP with:
// ===== MAIN GENERATION LOOP =====
for (i = [0 : num_cubes - 1]) {
size_i = outer_size - 2*i*(wall + clearance);
if (size_i > 0) {
// Outer cube
if (i == 0) {
outer_with_windows(size_i, wall);
}
// Middle hollow cubes
else if (i < num_cubes - 1) {
hollow_cube(size_i, wall);
}
// Innermost cube (smaller but trapped)
else {
safe_cube((size_i - clearance) * inner_scale);
}
}
}
Now the design has:
perfectly uniform gaps
no corner interference
maximum chance of free movement
proper print-in-place geometry
still visually clear through windows
But the version that I will print will also have just 2 cubes inside. So I also changed num_cubes to 2 from 3.
Our final code before the printing process.
// ===== GLOBAL PARAMETERS =====
outer_size = 30; // overall size of outer cube
wall = 2; // wall thickness
clearance = 0.4; // gap between moving parts
num_cubes = 2; // total nested cubes
inner_scale = 0.80; // makes the smallest cube smaller (0.6–0.9 is good)
$fn = 64;
// ===== SAFE INNER CUBE (anti-fusion) =====
module safe_cube(size) {
minkowski() {
cube(size - 0.6, center=true);
sphere(0.3);
}
}
// ===== HOLLOW CUBE =====
module hollow_cube(size, wall_thickness) {
difference() {
cube(size, center=true);
cube(size - 2*wall_thickness, center=true);
}
}
// ===== OUTER CUBE WITH WINDOWS =====
module outer_with_windows(size, wall_thickness) {
difference() {
hollow_cube(size, wall_thickness);
win = size * 0.4;
for (axis = [[1,0,0], [0,1,0], [0,0,1]]) {
rotate(
a = axis==[1,0,0] ? [0,90,0] :
axis==[0,1,0] ? [90,0,0] :
[0,0,0]
)
cube([win, win, size*2], center=true);
}
}
}
// ===== MAIN GENERATION LOOP =====
for (i = [0 : num_cubes - 1]) {
size_i = outer_size - 2*i*(wall + clearance);
if (size_i > 0) {
// Outer cube
if (i == 0) {
outer_with_windows(size_i, wall);
}
// Middle hollow cubes
else if (i < num_cubes - 1) {
hollow_cube(size_i, wall);
}
// Innermost cube (smaller but trapped)
else {
safe_cube((size_i - clearance) * inner_scale);
}
}
}

Printing Strategy Overview
For this nested cube, the goal is to produce a true print-in-place mechanism. That means all parts are printed already assembled and free to move, without any post-assembly. Because of this, internal supports would be harmful: if supports were generated inside the cube, they would be trapped and impossible to remove.
Instead of supports, the design relies on three principles:
I designed sufficient clearances between moving parts so the cubes do not fuse during printing. I also ensured that the window openings and wall thicknesses avoid unsupported horizontal spans that would require support material. Finally, the geometry is oriented so that each new layer is adequately supported by the layer beneath it, which allows the printer to bridge small gaps safely.
This is exactly why the object demonstrates an advantage of additive manufacturing over subtractive methods.
What We Do About Supports
Supports must be turned OFF.
In the slicer (Cura, PrusaSlicer, Bambu Studio, etc.) I will:
disable supports entirely
keep the cube resting flat on one face
rely on the printer’s natural bridging ability
The inner cube does not need supports because it is gradually formed layer by layer inside the cavity. Each layer of the inner cube is printed onto previously printed material beneath it. The printer never needs to print the inner cube “in mid-air.”
This is the key conceptual point many beginners miss.
Recommended Slicer Settings
For a reliable print-in-place result, I will use conservative but safe settings.
Layer height should be around 0.2 mm. This balances print quality and reliability. Very thick layers can reduce clearance accuracy.
Wall count should be two or three perimeters to ensure the cube walls are strong enough.
Infill can be kept relatively low, around 15–20%, since this object is primarily demonstrative rather than structural.
Supports must remain OFF.
Horizontal expansion (if your slicer has it) should be zero unless your printer is known to print tight.
PLA is the safest first material because it bridges well and has low stringing compared to PETG.
Print Orientation
I will print the cube sitting flat on one face of the outer cube.
This orientation:
maximizes bed adhesion
minimizes unsupported overhangs
keeps internal clearances consistent
avoids the need for supports
Rotating the model onto a corner or edge would increase failure risk and is not recommended.
After Printing
When the print finishes, the inner cube may initially feel slightly stuck. This is normal for print-in-place mechanisms.
To free it, I will gently twist or shake the outer cube until the inner cube breaks free. No cutting or disassembly should be required.
If the cube does not move at all, the clearance may be too small for the specific printer, and the model can be regenerated in OpenSCAD by slightly increasing the clearance parameter.
Printing Process
Part 1 — Export the model from OpenSCAD
First, open your final nested cube file in OpenSCAD.
Before exporting, you must do a full render, not just preview. Press F6 and wait until the rendering finishes. This step is critical because OpenSCAD only generates the true solid geometry during full render.
Once rendering completes:
- Go to File → Export → Export as STL

- Save the file with a clear name such as “nested_cube_print_in_place.stl”
Now your model is ready for slicing.
Part 2 — Open the model in Bambu Studio
Launch Bambu Studio.

On the start screen:
Click “Open Project” or simply drag your STL file into the build plate area.
Select your exported STL.
The cube should appear centered on the build plate.

Part 3 — Verify model orientation (very important)
You want the cube sitting flat on one face.
In Bambu Studio:
Select the model.
Click “Lay on Face” (top toolbar).

- Click one of the large outer cube faces.
OR
Select the model.
Click “Auto Orient” (top toolbar).

You should now see the cube resting flat on the plate.
This minimizes overhangs
Improves bridging
Prevents unnecessary supports
Part 4 — Set correct print profile
On the left panel:
Choose your printer model
Select PLA as the material (recommended for first print)

- Choose a standard profile like 0.20 mm Standard

Recommended starting values:
- Layer height: 0.20 mm

- Wall loops: 2 or 3

- Infill: 15–20% This is 20% by default

- Sparse infill pattern: default is fine

Part 5 — CRITICAL: Support settings
This is the most important part for print-in-place.
In the right settings panel:
Find Support
Set Support = OFF

If you want the conservative option:
- Support → Build plate only

But normally for your cube:
Supports OFF is correct (Still I will go with supports that are build on the plate only, which you might do to follow all steps exactly)
No internal support should be generated
After this, look at the preview — there should be no support structures inside the cube windows.
Part 6 — Slice the model
Click the big “Slice Plate” button.
After slicing completes:
Switch to Preview mode
Use the layer slider on the right
Carefully check:
Inner cube appears gradually layer by layer
No supports inside
Clear visible gaps between cubes
No strange floating regions

This preview check is extremely important
Part 7 — Optional but recommended checks
Before printing, quickly verify:
- Seam position: default is fine

- Brim: usually not needed for a cube

- Elephant foot compensation: leave default

- Horizontal expansion: 0 (important for tolerances)

Part 8 — Send to printer
If everything looks correct:
- Click “Print Plate”

- Or “Export G-code” if printing via SD card

Make sure the printer has:
Clean bed
Proper bed leveling
PLA loaded
Part 9 — After printing
When the print finishes:
Let it cool completely
Remove from plate
- Gently twist the cube to free motion
Please enjoy this “first break free” moment =D
Other Similar Projects That You Might Want To Check Out:
3D Scanning
For my 3D Scanning, I used Shining 3D EinStar 3D.

I plugged the cables of the device as shown in the image below:

I began the 3D scanning process by launching the Einstar software.
From the start screen, I selected the option to begin a new scan and confirmed that the scanner was properly connected and recognized by the software.
Before attempting the actual capture, I performed the required device calibration to ensure accurate depth and alignment performance. I followed the on-screen calibration guide and completed the procedure successfully, which is important for improving scan precision and reducing tracking errors.

After calibration, I created a new project group.

And after that, I moved to the scan setup stage. Since my goal was to capture a face portrait, I selected the appropriate scanning mode for human subjects.

Before recording any geometry, I used the live preview feature to check framing, distance, and lighting conditions. During this preview step, I adjusted my position relative to the scanner to ensure that my entire face was clearly visible and within the recommended working distance. I also verified that the tracking indicators in the software were stable, since poor tracking at this stage can lead to holes or drift in the final model.

Once the preview looked stable, I started the actual scan. I remained as still as possible while the scanner captured my face from multiple angles. The operator slowly moved the scanner around my head to ensure full coverage of the facial geometry, including the sides and under the chin. Throughout the capture process, I monitored the live reconstruction view to confirm that the mesh was filling in properly and that no major gaps were forming.

After sufficient coverage was achieved, I stopped the scan and proceeded to the post-processing stage. In the processing panel, I used the built-in tools to clean the scan by removing floating artifacts and trimming unwanted background geometry.


I then performed mesh fusion to generate a unified surface model from the captured point cloud data. Where necessary, I applied hole filling to close small gaps in the mesh while being careful not to distort important facial features.


After it meshes, confirm it.

With the cleaned mesh ready, I reviewed the model from multiple angles to verify completeness and surface quality. Once satisfied, I finalized the scan and exported the model. I chose the .3mf format for compatibility with downstream workflows such as slicing or further CAD processing. The file was saved with an appropriate project name for documentation and future use.

Advantages and Limitations of 3D Printing
Advantages
- Enables complex geometries
3D printing can produce internal cavities, moving parts, and enclosed features (like your cube-in-cube design) that are very difficult or impossible with subtractive manufacturing.
- Rapid prototyping
Designs can be quickly modified in OpenSCAD and reprinted without needing new tooling. This greatly speeds up iteration.
- Material efficiency
Additive manufacturing builds only what is needed, producing less waste compared to milling or cutting processes.
- Customization and low-volume production
Each print can be unique without increasing manufacturing complexity, making it ideal for personalized objects.
- Integrated assemblies
Multiple parts can be printed in place as a single object, reducing post-assembly work.
Limitations
- Support requirements
Overhangs and enclosed geometries often require supports. Removing supports inside tight spaces can be difficult or impossible.
- Surface finish and accuracy
Layer lines and minor dimensional inaccuracies are common compared to CNC machining.
- Mechanical strength anisotropy
Printed parts are weaker between layers (Z-direction), which can affect durability.
- Print time constraints
Complex prints can take hours, and large parts may exceed machine limits.
- Material limitations
Consumer printers typically support a limited range of thermoplastics compared to industrial manufacturing methods.