3dSynth

Tutorials / Custom G-code

Open in the interactive tutorials reader

---
title: Tutorial 33 Toolpath Optimization
description: Printing smarter, not harder.
---

Tutorial 33 Toolpath Optimization

1. Lesson Header

2. Concept Introduction

The Traveling Salesman Problem.
A printer spends 10-30% of its time moving without printing (Travel Moves).
We want to visit all required print segments while minimizing total travel distance.
This is a classic NP-Hard problem, but simple heuristics (Nearest Neighbor) work well enough.

3. Machine State Explanation

Cost Function.
Cost = Distance(Current_XY, Next_Start_XY).
We want to pick the Next_Start_XY that has the lowest cost.

4. Command Breakdown

5. Minimal Working Example

The Naive vs Optimized Path.
Points: A(0,0), B(100,100), C(10,10).
Naive Order (ABC): 0 -> 100 -> 10 (Total ~240mm).
Optimized Order (ACB): 0 -> 10 -> 100 (Total ~140mm).

6. Visual Representation

Interactive preview is available in the interactive reader.

7. Build Exercise

Task: Optimize a "Star Field".
Generate 100 random points.
Print a small dot at each point.
Compare the time taken for:
1. Random Order.
2. Sorted Order (Nearest Neighbor).

Algorithm:
1. Start at (0,0).
2. Find closest unvisited point.
3. Move there.
4. Mark visited.
5. Repeat.

8. Deep Insight Section

Start Point Optimization.
For closed loops (perimeters), you can start anywhere on the loop.
Slicers try to align the start point (Seam) to hide it, or to be close to the previous loop's end point.
Optimizing seam placement is a trade-off between aesthetics and speed.

9. Common Failure Modes

  1. Greedy Trap: Nearest Neighbor is "Greedy". It might leave an isolated point far away for last, forcing a huge travel move at the end.
  2. Crossing Perimeters: Sometimes the shortest path crosses an already printed wall, leaving a scar. Slicers add "Combing" (detours) to avoid this.

10. Real-World Application

PCB Drilling (CNC).
Drilling thousands of holes in a circuit board.
Optimizing the drill path saves hours of machine time.
The exact same logic applies to 3D printing "Retraction Hops".

11. Final Clean Version

The Optimizer Script:

import math
import random

points = [(random.randint(0, 200), random.randint(0, 200)) for _ in range(50)]

def dist(p1, p2):
    return math.hypot(p1[0]-p2[0], p1[1]-p2[1])

# Nearest Neighbor Sort
sorted_points = []
current = (0, 0) # Home
unvisited = points[:]

while unvisited:
    # Find closest
    closest = min(unvisited, key=lambda p: dist(current, p))
    sorted_points.append(closest)
    unvisited.remove(closest)
    current = closest

# Generate G-code
with open("optimized_stars.gcode", "w") as f:
    f.write("G28\nG1 Z0.2\n")
    for p in sorted_points:
        f.write(f"G0 X{p[0]} Y{p[1]} F9000\n") # Travel fast
        f.write("G1 E0.1 F1000\n")  # Dot
        f.write("G1 E-0.1 F1000\n") # Retract
    f.write("G28 X0 Y0\n")

12. Stretch Challenge

Challenge: Implement "Two-Opt" Optimization.
After the greedy sort, try swapping pairs of edges to see if the total length decreases.
This untangles crossed paths.
Hint: If path A->B and C->D intersect, swapping to A->C and B->D is usually shorter.