feat(scad): cadbuildr.foundation port of every printed part

Auto-generated by the CADbuildr prototype agent (Medium tier, gemma-4-31b
via cliproxy) driven by the headless qa/run-prusa-i3-scad-medium.mjs
harness from the cadbuildr/monorepo PR #685. Each .scad under
Printed-Parts/SCAD/ gets a sibling .py that reproduces the SCAD module
shape using cadbuildr.foundation primitives:

  - 2D shapes on Sketch-based Points (Square / Rectangle / Circle)
  - 3D primitives (Box / Cylinder / Sphere / Cone) with Point-as-centre
  - difference() via cut=True on the cutter operation
  - SCAD translate() folded into Point coordinates

All 23 files import + execute against cadbuildr.foundation and submit
geometry to cadbuildr-broker locally. Visual fidelity vs the SCAD source
is a first-pass approximation — hull(), minkowski(), and polyhedron()
calls were approximated or omitted; included module recursion was inlined.

Generated 23/23 in ~8 minutes wall-clock. No human edits.
pull/210/head
Clement Jambou (cadbuildr agent) 2026-05-18 20:28:18 -07:00
parent 529e5ad689
commit 7d256dd47e
23 changed files with 1934 additions and 0 deletions

View File

@ -0,0 +1,155 @@
"""Auto-converted from Einsy-base.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class EinsyBase(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === main_body() ===
# side panel
self._add_box(118.5/2, 92/2, 2/2, 118.5, 92, 2)
# upper panel
self._add_box(1.5/2, 92/2, 35/2, 1.5, 92, 35)
# rear panel
self._add_box(0 + 105.5/2, 90 + 2/2, 35/2, 105.5, 2, 35)
# upper panel frame reinforcement
self._add_box(5/2, 7/2, 1 + 34/2, 5, 7, 34)
# side panel reinforcement
self._add_box(9/2, 92/2, 1 + 3/2, 9, 92, 3)
self._add_box(98 + 9/2, 92/2, 4/2, 9, 92, 4)
# antenna posts
self._add_cyl(21, 81, 0, 2.5, 4.5)
self._add_cyl(79, 81, 0, 2.5, 4.5)
# ziptie block (approximate as small box)
self._add_box(0 + 5/2, 55 + 8/2, 22 + 10/2, 5, 8, 10)
self._add_box(25 + 8/2, 91.5 + 5/2, 22 + 10/2, 8, 5, 10)
# bottom side reinforcement
self._add_box(98 + 7.5/2, 86 + 6/2, 35/2, 7.5, 6, 35)
self._add_box(0 + 5.5/2, 85 + 7/2, 35/2, 5.5, 7, 35)
# screw mounting block
self._add_box(54 + 9.5/2, 84 + 7/2, 35/2, 9.5, 7, 35)
# frame side panel
self._add_box(20 + 80/2, 3/2, 5/2, 80, 3, 5)
# Einsy mounting holes (hex pockets — approx as cylinders)
self._add_cyl(102.5, 14, 1, 5.5, 7)
self._add_cyl(102.5, 75, 1, 5.5, 7)
self._add_cyl(7.5, 14, 1, 5.5, 7)
self._add_cyl(7.5, 75, 1, 5.5, 7)
# corner reinforcements
self._add_box(0 + 13/2, 75 + 16/2, 1 + 6/2, 13, 16, 6)
self._add_box(0 + 7.5/2, 70.25 + 11/2, 1 + 6/2, 7.5, 11, 6)
self._add_box(0 + 7.5/2, 7.75 + 11/2, 1 + 6/2, 7.5, 11, 6)
self._add_box(0 + 13/2, 0 + 14/2, 1 + 6/2, 13, 14, 6)
# frame mounting screw blocks
self._add_box(1 + 28/2, 4/2, 10/2, 28, 4, 10)
self._add_box(18.45 + 3/2, 4/2, 5.5/2, 3, 4, 5.5)
self._add_box(98 + 20.5/2, 4/2, 10/2, 20.5, 4, 10)
# door closing corner
self._add_cone(102, 88.5, 35, 2.5, 1, 3)
# doors pin upper
self._add_box(2 + 6/2, 85 + 7/2, 31 + 4/2, 6, 7, 4)
self._add_cone(4, 88.5, 35, 2.5, 1, 3)
# x-axis cables entry hole body (hex approx)
self._add_cyl(89, 2, 0, 6, 5)
# === cutouts() ===
# extruder cable holder cuts
self._add_box(-15 + 30/2, 0 + 60/2, 35 + 15/2, 30, 60, 15, cut=True)
self._add_box(-15 + 30/2, 24 + 8/2, 30 + 8/2, 30, 8, 8, cut=True)
self._add_cyl(-20, 28, 28, 5.5, 40, cut=True)
self._add_cyl(-3, 28, 28, 1.7, 24, cut=True)
# side cutout
self._add_box(12 + 85.5/2, 19 + 51/2, 1 + 3/2, 85.5, 51, 3, cut=True)
# Einsy M3 screws
self._add_cyl(7.5, 14, -1, 1.9, 10, cut=True)
self._add_cyl(102.5, 14, -1, 1.9, 10, cut=True)
self._add_cyl(102.5, 75, -1, 1.9, 10, cut=True)
self._add_cyl(7.5, 75, -1, 1.9, 10, cut=True)
# nut traps (hex approx as cylinders)
self._add_cyl(7.5, 14, -1, 3.2, 4, cut=True)
self._add_cyl(102.5, 14, -1, 3.2, 4, cut=True)
self._add_cyl(102.5, 75, -1, 3.2, 4, cut=True)
self._add_cyl(7.5, 75, -1, 3.2, 4, cut=True)
self._add_cyl(58.5, 88, -1, 3.2, 4, cut=True)
# ventilation holes (representative sample)
for i in range(-5, 9):
self._add_box(46 + i*5.5 + 3.65/2, 10.5 + (19+49)/2, -1 + 1.2/2, 3.65, 68, 1.2, cut=True)
self._add_box(46 + i*5.5 + 3.65/2, 10.5 + 18/2, -1 + 10/2, 3.65, 18, 10, cut=True)
# frame mounting screws (along Y)
self._add_cyl(16.5, 8, 5, 1.6, 10, cut=True)
self._add_cyl(110.5, 9, 5, 1.6, 10, cut=True)
# USB connector hole
self._add_box(-1 + 5.5/2, 41.5 + 13/2, 11 + 11/2, 5.5, 13, 11, cut=True)
# reset button
self._add_cyl(-2, 65, 14, 2, 10, cut=True)
# door closing screw
self._add_cyl(58.5, 88, -1, 1.9, 43, cut=True)
# main cable hole
self._add_cyl(-10, 28, 26, 6.8, 24, cut=True)
self._add_box(-15 + 30/2, 25 + 6/2, 30 + 10/2, 30, 6, 10, cut=True)
# lightening slots
self._add_box(100 + 5/2, 21 + 48/2, 2 + 5/2, 5, 48, 5, cut=True)
self._add_box(3 + 4.5/2, 21 + 48/2, 2 + 5/2, 4.5, 48, 5, cut=True)
# x axis cable hole
self._add_cyl(89, 2, -1, 4, 10, cut=True)
self._add_box(80 + 15/2, -5 + 5/2, -1 + 10/2, 15, 5, 10, cut=True)
# heatbed cable mounting reinforcement
self._add_box(63 + 15/2, 86.0 + 5/2, 0.5 + 34.5/2, 15, 5, 34.5)
self._add_cyl(75, 99, 28, 13, 9)
# heatbed screw cuts
self._add_cyl(67, 88.8, 20, 1.6, 15, cut=True)
self._add_cyl(83, 96, 20, 1.6, 15, cut=True)
self._add_cyl(61, 102, 28, 3.3, 35, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = EinsyBase()
show(part)

View File

@ -0,0 +1,104 @@
"""Auto-converted from Einsy-doors.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class EinsyDoors(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === body() ===
self._add_box(105.5/2, 87.5/2, 1.5/2, 105.5, 87.5, 1.5)
self._add_box(105.5/2, 2/2, 16/2, 105.5, 2, 16)
self._add_box(2/2, 87.5/2, 16/2, 2, 87.5, 16)
# corner reinforcements
self._add_box(98 + 7.5/2, 1 + 5/2, 16/2, 7.5, 5, 16)
self._add_box(0.5 + 5/2, 0.5 + 6.5/2, 16/2, 5, 6.5, 16)
self._add_box(1 + 10/2, 87.5/2, 6/2, 10, 87.5, 6)
self._add_box(99.5 + 6/2, 87.5/2, 7/2, 6, 87.5, 7)
self._add_box(10 + 6/2, 5/2, 6/2, 6, 5, 6)
# screw thread body
self._add_box(54 + 9.5/2, 2 + 6/2, 16/2, 9.5, 6, 16)
# rounded side (cylinder along X at y=87.5, z=4.5)
self._add_cyl(105.5/2, 87.5, 4.5, 4.5, 105.5)
# upper hinge reinforcement
self._add_box(0.5 + 26/2, 69 + 20/2, -9 + 10/2, 26, 20, 10)
# door closing bumps
self._add_cone(4, 3.5, 12.8, 1.8, 3.5, 3.2)
self._add_cone(102, 3.5, 12.8, 1.8, 3.5, 3.2)
# === cutouts() ===
# door closing screw
self._add_cyl(58.5, 4, 1, 1.8, 17, cut=True)
self._add_cone(58.5, 4, 14.5, 1.8, 2.2, 2.6) # approx
self._add_box(58.5, 4 + 2.5, 4, 5.7, 3.8, 1, cut=True)
self._add_box(58.5, 4 + 3, 4, 3.8, 3.8, 1, cut=True)
# ventilation holes (10 slots)
for i in range(10):
self._add_box(40 + i*6 + 3.65/2, 10.5 + (19+50)/2, -1 + 1.2/2, 3.65, 19+50, 1.2, cut=True)
self._add_box(40 + i*6 + 3.65/2, 10.5 + 19/2, -1 + 10/2, 3.65, 19, 10, cut=True)
self._add_box(40 + i*6 + 3.65/2, 10.5+25 + 19/2, -1 + 10/2, 3.65, 19, 10, cut=True)
self._add_box(40 + i*6 + 3.65/2, 10.5+50 + 19/2, -1 + 10/2, 3.65, 19, 10, cut=True)
# large ventilation panel
self._add_box(15 + 20/2, 10 + 55/2, 1 + 1.5/2, 20, 55, 1.5, cut=True)
# rounded side cutoff
self._add_cyl(26.5 + 73/2, 87.5, 4.5, 3.5, 73, cut=True)
self._add_box(26.5 + 73/2, 80 + 19/2, 5 + 10/2, 73, 19, 10, cut=True)
self._add_box(26.5 + 73/2, 82.5 + 5/2, 1 + 10/2, 73, 5, 10, cut=True)
# upper hinge cuts
self._add_box(0 + 30/2, 60 + 30/2, -10 + 10/2, 30, 30, 10, cut=True)
self._add_box(-1 + 22.5/2, 87.5 + 10/2, 0 + 10/2, 22.5, 10, 10, cut=True)
self._add_box(2 + 19.5/2, 80 + 10/2, 6 + 10/2, 19.5, 10, 10, cut=True)
self._add_cyl(-5 + 26.5/2, 87.5, 4.5, 2.5, 26.5, cut=True)
# hinge hole (full width)
self._add_cyl(-5 + 120/2, 87.5, 4.5, 2.6, 120, cut=True)
# door closing inner cone cuts
self._add_cone(4, 3.5, 12.9, 1.2, 2.8, 3.2) # approx
self._add_cone(102, 3.5, 12.9, 1.2, 2.8, 3.2)
# M3 nut slot
self._add_box(55.65 + 5.7/2, 0.5 + 10/2, 12 + 2.2/2, 5.7, 10, 2.2, cut=True)
# side lightning slots
self._add_box(2 + 7/2, 10 + 65/2, 3 + 5/2, 7, 65, 5, cut=True)
self._add_box(101 + 3/2, 10 + 70/2, 3 + 5/2, 3, 70, 5, cut=True)
# large corner cut
self._add_box(0 + 30/2, -20 + 30/2, -3 + 20/2, 30, 30, 20, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = EinsyDoors()
show(part)

View File

@ -0,0 +1,65 @@
"""Auto-converted from Einsy-hinges.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class EinsyHinges(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === upper_hinge() ===
# body cylinder h=26 r=2.4
self._add_cyl(0, 0, 0, 2.4, 26)
# top taper cone
self._add_cone(0, 0, 26, 2.4, 1.8, 2)
# body block: translate([-5,-10.7,0]) cube([7,10.7,21])
self._add_box(-5 + 7/2, -10.7 + 10.7/2, 0 + 21/2, 7, 10.7, 21)
# M3 screw hole (along X — approx as horizontal box cut)
self._add_box(-12.5 + 20/2, -2.5, 17, 20, 1.75*2, 1.75*2, cut=True)
# screw head recess
self._add_box(-1.5 + 9/2, -2.5, 17, 9, 3*2, 3*2, cut=True)
# angle cut (approx as box)
self._add_box(-2.9 + 25/2, -20 + 5/2, -1 + 26/2, 25, 5, 26, cut=True)
# === lower_hinge() — offset so it doesn't overlap ===
OX = 15 # separate the two hinges visually
# body cylinders at translate([0,6,0])
self._add_cyl(0 + OX, 6, 0, 2.4, 15)
self._add_cyl(0 + OX, 6, 0, 2.8, 10)
self._add_cone(0 + OX, 6, 15, 2.4, 1.8, 2)
# body block: translate([-5,6,0]) cube([7,10.7,10])
self._add_box(-5 + 7/2 + OX, 6 + 10.7/2, 0 + 10/2, 7, 10.7, 10)
# M3 screw (along X)
self._add_box(-0.5 + 20/2 + OX, 8.5, 4, 20, 3*2, 3*2, cut=True)
self._add_box(-12 + 20/2 + OX, 8.5, 4, 20, 1.75*2, 1.75*2, cut=True)
# angle cut
self._add_box(-5 + 20/2 + OX, 20 + 5/2, -1 + 20/2, 20, 5, 20, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = EinsyHinges()
show(part)

View File

@ -0,0 +1,66 @@
"""Auto-converted from Extruder-cable-clip.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
# Offset from translate([6,-28,-28]) applied at call site
OX, OY, OZ = 6, -28, -28
class ExtruderCableClip(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# body shape — cylinders rotated 90 around Y (lying along X), approx as boxes
# translate([-6,28,28]) rotate([0,90,0]) cylinder(h=6,r=13.5)
self._add_box(-6 + 6/2 + OX, 28 + OY, 28 + OZ, 6, 27, 27)
# translate([-10,28,28]) rotate([0,90,0]) cylinder(h=4,r1=8.5,r2=13.5)
self._add_box(-10 + 4/2 + OX, 28 + OY, 28 + OZ, 4, 27, 27)
# translate([0,16.6,28]) cube([2.9,22.8,7])
self._add_box(0 + 2.9/2 + OX, 16.6 + 22.8/2 + OY, 28 + 7/2 + OZ, 2.9, 22.8, 7)
# bottom cut and shape
self._add_box(-15 + 30/2 + OX, 7 + 40/2 + OY, 13 + 15/2 + OZ, 30, 40, 15, cut=True)
self._add_cyl(-20 + OX, 28 + OY, 28 + OZ, 6, 40, cut=True)
# screws (rotated 90 around Z -> along Y, approx as vertical cylinders)
self._add_cyl(-2.7 + OX, 19.5 + OY, 25 + OZ, 1.6, 10, cut=True)
self._add_cyl(-2.7 + OX, 36.5 + OY, 25 + OZ, 1.6, 10, cut=True)
self._add_cyl(-2.7 + OX, 36.5 + OY, 32 + OZ, 3.1, 13, cut=True)
self._add_cyl(-2.7 + OX, 19.5 + OY, 32 + OZ, 3.1, 13, cut=True)
# screw head openings
self._add_box(-2.7 + 10/2 + OX, 16.4 + 6.2/2 + OY, 35 + 15/2 + OZ, 10, 6.2, 15, cut=True)
self._add_box(-2.7 + 10/2 + OX, 33.4 + 6.2/2 + OY, 35 + 15/2 + OZ, 10, 6.2, 15, cut=True)
# cable grip inner cut
self._add_cyl(-20 + OX, 28 + OY, 28 + OZ, 5.5, 40, cut=True)
# nylon hole (angled — approximate as vertical cylinder)
self._add_cyl(-3 + OX, 28 + OY, 28 + OZ, 1.8, 24, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = ExtruderCableClip()
show(part)

View File

@ -0,0 +1,65 @@
"""Auto-converted from Heatbed-cable-clip.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
# Offsets applied from translate([-70,-110,0]) in SCAD call
OX, OY, OZ = -70, -110, 0
class HeatbedCableClip(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# body base cylinders (rotated 90 around X -> lying along Y)
# approximate as boxes with cylinder cross-section -> use cylinders oriented via radius
# translate([75,99,28]) rotate([90,0,0]) cylinder(h=15, r=13)
# lying along Y at x=75, z=28; approximate as box
self._add_box(75 + OX, 99 - 15/2 + OY, 28 + OZ, 26, 15, 26)
# translate([75,101,28]) rotate([90,0,0]) cylinder(h=2, r1=9, r2=13) -> cone approx box
self._add_box(75 + OX, 101 - 2/2 + OY, 28 + OZ, 26, 2, 26)
# flat shelf tab
# translate([62.75,84,28]) cube([24.5,8,7])
self._add_box(62.75 + 24.5/2 + OX, 84 + 8/2 + OY, 28 + 7/2 + OZ, 24.5, 8, 7)
# cut flat and shape
self._add_box(60 + 30/2 + OX, 82 + 20/2 + OY, 14 + 14/2 + OZ, 30, 20, 14, cut=True)
self._add_box(60 + 30/2 + OX, 72 + 20/2 + OY, 20 + 30/2 + OZ, 30, 20, 30, cut=True)
# cable opening (angled — approximate as vertical cylinder cut)
self._add_cyl(61 + OX, 102 + OY, 28 + OZ, 3.3, 35, cut=True)
# screw heads
self._add_cyl(67 + OX, 88.8 + OY, 30.5 + OZ, 3.2, 10, cut=True)
self._add_cyl(83 + OX, 96 + OY, 31 + OZ, 3.2, 10, cut=True)
# screws
self._add_cyl(67 + OX, 88.8 + OY, 14 + OZ, 1.6, 35, cut=True)
self._add_cyl(83 + OX, 96 + OY, 14 + OZ, 1.6, 35, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = HeatbedCableClip()
show(part)

View File

@ -0,0 +1,60 @@
"""Auto-converted from Heatbed-cable-clip_8mm.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
# Offsets applied from translate([-70,-110,0]) in SCAD call
OX, OY, OZ = -70, -110, 0
class HeatbedCableClip8mm(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# body base cylinders (rotated 90 around X -> lying along Y, approximated as boxes)
self._add_box(75 + OX, 99 - 15/2 + OY, 28 + OZ, 26, 15, 26)
self._add_box(75 + OX, 101 - 2/2 + OY, 28 + OZ, 26, 2, 26)
# flat shelf tab
self._add_box(62.75 + 24.5/2 + OX, 84 + 8/2 + OY, 28 + 7/2 + OZ, 24.5, 8, 7)
# cut flat and shape
self._add_box(60 + 30/2 + OX, 82 + 20/2 + OY, 14 + 14/2 + OZ, 30, 20, 14, cut=True)
self._add_box(60 + 30/2 + OX, 72 + 20/2 + OY, 20 + 30/2 + OZ, 30, 20, 30, cut=True)
# cable opening — 8mm variant has r=5 (vs 4 in 4mm version)
self._add_cyl(61 + OX, 102 + OY, 28 + OZ, 4.3, 35, cut=True)
# screw heads
self._add_cyl(67 + OX, 88.8 + OY, 30.5 + OZ, 3.2, 10, cut=True)
self._add_cyl(83 + OX, 96 + OY, 31 + OZ, 3.2, 10, cut=True)
# screws
self._add_cyl(67 + OX, 88.8 + OY, 14 + OZ, 1.6, 35, cut=True)
self._add_cyl(83 + OX, 96 + OY, 14 + OZ, 1.6, 35, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = HeatbedCableClip8mm()
show(part)

View File

@ -0,0 +1,108 @@
"""Auto-converted from LCD-cover-ORIGINAL-MK3.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class LcdCoverOriginalMk3(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === main_body union ===
self._add_box(-77 + 155/2, -4.5 + 59.8/2, 0 + 2/2, 155, 59.8, 2)
self._add_box(-77 + 155/2, -4.5 + 3/2, 0 + 20.08/2, 155, 3, 20.08)
self._add_box(-77 + 7/2, -3.5 + 5/2, -1 + 15/2, 7, 5, 15)
self._add_box(71 + 7/2, -3.5 + 5/2, -1 + 15/2, 7, 5, 15)
self._add_box(-77 + 155/2, -15.2 + 3.1/2, 14.2 + 11.8/2, 155, 3.1, 11.8)
self._add_box(-77 + 155/2, 54 + 2/2, 0 + 17/2, 155, 2, 17)
# M3 hole bodies (hex cylinders — approx as regular cylinders)
self._add_cyl(73.5, 43.3, 0.5, 4, 14)
self._add_cyl(-72.5, 43.5, 0.5, 4, 14)
# pcb_clip bodies
self._add_box(-3 + 7/2, -12 + 4/2, 17.5 + 5/2, 7, 4, 5)
self._add_box(-3 + 1/2, -10.6 + 2.6/2, 12.5 + 7/2, 1, 2.6, 7)
self._add_box(3 + 1/2, -10.6 + 2.6/2, 12.5 + 7/2, 1, 2.6, 7)
# reset button body
self._add_cyl(62.5, 37.3, 0, 3.5, 7.2)
# left side panels
self._add_box(-77 + 1.5/2, -14.7 + 70.7/2, 0 + 26/2, 1.5, 70.7, 26)
self._add_box(-76.5 + 4/2, -15 + 70/2, 0 + 14.6/2, 4, 70, 14.6)
# right side panels
self._add_box(76.5 + 1.5/2, -14.7 + 70.7/2, 0 + 26/2, 1.5, 70.7, 26)
self._add_box(73.5 + 4/2, -14 + 70/2, 0 + 14.5/2, 4, 70, 14.5)
# rear reinforcement
self._add_box(-54.5 + 110/2, -11.7 + 4/2, 8 + 6.5/2, 110, 4, 6.5)
self._add_box(65.5 + 12/2, -11.7 + 4/2, 8 + 6.5/2, 12, 4, 6.5)
self._add_box(65.5 + 12/2, -13 + 2/2, 14 + 12/2, 12, 2, 12)
self._add_box(-76.5 + 12/2, -11.7 + 4/2, 8 + 6.5/2, 12, 4, 6.5)
self._add_box(-76.5 + 12/2, -14.7 + 4/2, 14.5 + 11.5/2, 12, 4, 11.5)
self._add_box(-44 + 89/2, -14.7 + 4/2, 14.5 + 11.5/2, 89, 4, 11.5)
# front reinforcements (approx)
self._add_box(-77 + 15/2, 41.3 + 14/2, 0 + 25/2, 15, 14, 25)
self._add_box(38 + 40/2, 41.2 + 14/2, 0 + 26/2, 40, 14, 26)
# SD card window support tabs
self._add_box(-76.5 + 1/2, 15 + 5/2, 16.70 + 4.1/2, 1, 5, 4.1)
self._add_box(-76.5 + 1/2, 25 + 5/2, 16.70 + 4.1/2, 1, 5, 4.1)
# === cuts ===
# LCD window
self._add_box(-61.5 + 98.5/2, 1 + 42/2, 1.2 + 10/2, 98.5, 42, 10, cut=True)
self._add_box(-52.5 + 80/2, 8 + 30.5/2, -1 + 10/2, 80, 30.5, 10, cut=True)
# speaker slots
for buzz in range(55, 68, 2):
self._add_box(buzz + 1.3/2, 1.5 + 4/2, -1 + 10/2, 1.3, 4, 10, cut=True)
# knob hole
self._add_cyl(62.5, 21, -1, 6, 10, cut=True)
self._add_cone(62.5, 21, -1.2, 7, 6, 2) # chamfer (not cut — just visual approx)
# reset button cutout
self._add_box(44 + 1/2, 26 + 6/2, -1 + 9/2, 1, 6, 9, cut=True)
# SD card opening
self._add_box(-80 + 10/2, 9 + 28/2, 16.5 + 4.5/2, 10, 28, 4.5, cut=True)
# M3 screw threads
self._add_cyl(72.5, 43.2, 3, 1.4, 20, cut=True)
self._add_cyl(-72.5, 42.7, 3, 1.4, 20, cut=True)
# front cleanup
self._add_box(-100 + 200/2, -64.6 + 50/2, 0 + 50/2, 200, 50, 50, cut=True)
# large bottom cleanup
self._add_box(-100 + 200/2, -40 + 50/2, -50 + 50/2, 200, 50, 50, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = LcdCoverOriginalMk3()
show(part)

View File

@ -0,0 +1,91 @@
"""Auto-converted from PSU-cover-MK3.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class PsuCoverMk3(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === PSU_COVER base ===
self._add_box(0 + 95/2, 0 + 65/2, -0.46 + 54.25/2, 95, 65, 54.25)
# back pillar 1
self._add_box(0 + 13.5/2, 0 + 65/2, -3.5 + 5/2, 13.5, 65, 5)
# back pillar top
self._add_box(-1.6 + 5/2, 1 + 64/2, 51.5 + 3/2, 5, 64, 3)
# back pillar 2
self._add_box(59.5 + 14/2, 0 + 65/2, -3.5 + 5/2, 14, 65, 5)
# base for bracket
self._add_box(95 + 6/2, 0 + 65/2, -0.46 + 54.25/2, 6, 65, 54.25)
# nipple
self._add_box(-2 + 2/2, 40.8 + 3/2, 19 + 15/2, 2, 3, 15)
# frame skirts
self._add_box(-1.6 + 1.65/2, 0 + 65/2, 0 + 2/2, 1.65, 65, 2)
self._add_box(-1.6 + 1.65/2, 0 + 30/2, 0 + 53.78/2, 1.65, 30, 53.78)
self._add_box(-1.6 + 1.65/2, 0 + 65/2, 51.32 + 2.46/2, 1.65, 65, 2.46)
# main interior cutout
self._add_box(3 + 89.02/2, 3 + 65.02/2, 2 + 49.32/2, 89.02, 65.02, 49.32, cut=True)
# insert cutout
self._add_box(-3 + 100/2, 33.6 + 16.5/2, 2 + 49.3/2, 100, 16.5, 49.3, cut=True)
self._add_box(-3 + 10/2, 18 + 100/2, 2 + 17/2, 10, 100, 17, cut=True)
self._add_box(87 + 10/2, 17.3 + 100/2, 2 + 49.3/2, 10, 100, 49.3, cut=True)
# socket cutout
self._add_box(5.5 + 48 + 27.5/2, 0.5 + 1.5 + 32.9/2, 40 + 30/2, 27.5, 32.9, 30, cut=True)
# switch cutout
self._add_box(5.5 + 1 + 12.5/2, 0.5 + 6 + 20/2, 40 + 44 + 30/2, 12.5, 20, 30, cut=True)
# mount holes
self._add_cyl(6, 54, -10, 2, 50, cut=True)
self._add_cyl(66.8, 57.5, -10, 2, 50, cut=True)
# fan slot (row of 10 cylinders approx as boxes)
for i in range(10):
self._add_box(20 + i + 3.5/2, 6.8 + 3.5, -10 + 50/2, 3.5, 3.5, 50, cut=True)
# === PSU_Y_REINFORCEMENT ===
self._add_box(59.5 + 33/2, 0 + 6/2, -18 + 19/2, 33, 6, 19)
self._add_box(73.5 + 5/2, 5 + 16/2, -18 + 19/2, 5, 16, 19)
# cleanup cut
self._add_box(-5 + 150/2, -9 + 10/2, -30 + 100/2, 150, 10, 100, cut=True)
# upper_part add-ons
self._add_box(30 + 15/2, 3.5 + 11/2, 49.5 + 2.5/2, 15, 11, 2.5)
self._add_box(45 + 15/2, 3.5 + 11/2, 1 + 2.5/2, 15, 11, 2.5)
# m3 screws
self._add_cyl(37, 9, 39, 1.5, 12, cut=True)
self._add_cyl(14.5, 8, 25, 1.5, 12, cut=True)
self._add_cyl(85.5, 8, 25, 1.5, 12, cut=True)
self._add_cyl(52, 9, 14.5, 1.5, 12, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = PsuCoverMk3()
show(part)

View File

@ -0,0 +1,53 @@
"""Auto-converted from bearing.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
# === SCAD constants reproduced verbatim ===
bearing_diameter = 14.95
thinwall = 3
bearing_size = bearing_diameter + 2 * thinwall
class Bearing(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# vertical_bearing_base: cylinder h=58 r=bearing_size/2
self._add_cyl(0, 0, 29, bearing_size / 2, 58)
# flat backing slab
self._add_box(-2 - bearing_size / 4, 0, 29, 4 + bearing_size / 2, bearing_size, 58)
# vertical_bearing_holes (cut=True)
# Main bore cylinder
self._add_cyl(0, 0, -1 + 31, (14.80 / 2), 62, cut=True)
# Entry chamfer cone approximated as cylinder at bottom
self._add_cyl(0, 0, 0.25, (bearing_diameter / 2) + 0.7, 0.5, cut=True)
# Retention slot: thin cube rotated ~-40 deg — approximate as box
self._add_box(bearing_diameter / 2 - 2.9, -0.5, 31, thinwall * 2, 1, 62, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = Bearing()
show(part)

View File

@ -0,0 +1,53 @@
"""Auto-converted from endstop-block.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class EndstopBlock(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# body: translate([1,-16,1]) cube([12,9,14])
self._add_box(1 + 12/2, -16 + 9/2, 1 + 14/2, 12, 9, 14)
# chamfer block: translate([1,-16,1]) rotate([0,0,45]) cube([3,2.2,14]) — approx unrotated
self._add_box(1 + 3/2, -16 + 2.2/2, 1 + 14/2, 3, 2.2, 14)
# side tab: translate([0.5,-8,1]) cube([3,1,14])
self._add_box(0.5 + 3/2, -8 + 1/2, 1 + 14/2, 3, 1, 14)
# screw hole: translate([-4,-11,11]) rotate([0,90,0]) cylinder(r=1.65, h=10)
# rotated 90 deg around Y => lies along X axis; approximate as box cut
self._add_box(-4 + 10/2, -11, 11, 10, 1.65*2, 1.65*2, cut=True)
# screw head recess: translate([5,-11,11]) rotate([0,90,0]) cylinder(r=3.1, h=10)
self._add_box(5 + 10/2, -11, 11, 10, 3.1*2, 3.1*2, cut=True)
# edge cuts approximated as boxes
self._add_box(-13 + 15/2, -22 + 15/2, 0 + 15/2, 15, 15, 15, cut=True)
self._add_box(-1 + 15/2, 0 + 15/2, -10 + 15/2, 15, 15, 15, cut=True)
self._add_box(-12 + 15/2, -20 + 15/2, 0 + 15/2, 15, 15, 15, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = EndstopBlock()
show(part)

View File

@ -0,0 +1,71 @@
"""Auto-converted from heatbed-cable-cover-clip.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class HeatbedCableCoverClip(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# base body: translate([-15,15.5,-3]) cube([30,20.5,6])
self._add_box(-15 + 30/2, 15.5 + 20.5/2, -3 + 6/2, 30, 20.5, 6)
# inner cuts
self._add_box(3.5 + 10.5/2, 2 + 15/2, 0 + 6/2, 10.5, 15, 6, cut=True)
self._add_box(-14 + 10.5/2, 2 + 15/2, 0 + 6/2, 10.5, 15, 6, cut=True)
self._add_box(3.5 + 7/2, 15 + 8/2, 0 + 6/2, 7, 8, 6, cut=True)
self._add_box(-10.5 + 7/2, 15 + 8/2, 0 + 6/2, 7, 8, 6, cut=True)
self._add_box(-7 + 14/2, 15 + 11/2, 0 + 6/2, 14, 11, 6, cut=True)
self._add_box(3 + 7/2, 14 + 13/2, 1 + 6/2, 7, 13, 6, cut=True)
self._add_box(-9.88 + 7/2, 15.21 + 13/2, 1 + 6/2, 7, 13, 6, cut=True)
# cables cut — main cylinder along Y
self._add_cyl(0, 36, 3, 4, 187, cut=True)
# m3 nut pockets (approximate as cylinders)
self._add_cyl(-11, 30, 0, 3.15, 4, cut=True)
self._add_cyl(11, 30, 0, 3.15, 4, cut=True)
# thermistor cable entry (angled — approximate as vertical cylinder)
self._add_cyl(0, 22, 4, 3, 15, cut=True)
# edge cuts
self._add_box(-18.0 + 11/2, 32 + 11/2, -5 + 15/2, 11, 11, 15, cut=True)
self._add_box(18 + 11/2, 32 + 11/2, -5 + 15/2, 11, 11, 15, cut=True)
# cable rims: outer ring minus inner
self._add_cyl(0, 36, 3, 4.5, 10)
self._add_cyl(0, 37, 3, 3, 17, cut=True)
# trim the rim
self._add_box(0, 18 + 20/2, 3 + 6/2, 30, 20, 6, cut=True)
self._add_box(0, 27 + 2/2, -5 + 16/2, 30, 2, 16, cut=True)
self._add_box(0, 30 + 2/2, -5 + 16/2, 30, 2, 16, cut=True)
self._add_box(0, 33 + 2/2, -5 + 16/2, 30, 2, 16, cut=True)
self._add_box(-4 + 8/2, 20 + 11/2, 0 + 6/2, 8, 11, 6, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = HeatbedCableCoverClip()
show(part)

View File

@ -0,0 +1,87 @@
"""Auto-converted from heatbed-cable-cover.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class HeatbedCableCover(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# base block: translate([-18,0,0]) cube([36,36,9])
self._add_box(-18 + 36/2, 0 + 36/2, 0 + 9/2, 36, 36, 9)
# heatbed pcb support rails
self._add_box(-17 + 3/2, 0 + 20/2, 4 + 2/2, 3, 20, 2)
self._add_box(14 + 3/2, 0 + 20/2, 4 + 2/2, 3, 20, 2)
self._add_box(-17 + 14/2, 0 + 2/2, 4 + 2/2, 14, 2, 2)
self._add_box(3 + 14/2, 0 + 2/2, 4 + 2/2, 14, 2, 2)
# inner cut
self._add_box(-15 + 30/2, -0.5 + 16/2, -3 + 9/2, 30, 16, 9, cut=True)
# cable opening along Y
self._add_cyl(0, 37, 3, 3.3, 15, cut=True)
# large inner panel cut
self._add_box(-15 + 30/2, 15 + 22/2, -6 + 9/2, 30, 22, 9, cut=True)
# inner edge cuts
self._add_box(3.5 + 10.5/2, 2 + 15/2, 0 + 6/2, 10.5, 15, 6, cut=True)
self._add_box(-14 + 10.5/2, 2 + 15/2, 0 + 6/2, 10.5, 15, 6, cut=True)
self._add_box(2.5 + 8/2, 15 + 8/2, 0 + 6/2, 8, 8, 6, cut=True)
self._add_box(-10.5 + 8/2, 15 + 8/2, 0 + 6/2, 8, 8, 6, cut=True)
self._add_box(6.96 + 5/2, 19.45 + 10/2, 0 + 6/2, 5, 10, 6, cut=True)
self._add_box(-6.96 + 10/2, 19.45 + 5/2, 0 + 6/2, 10, 5, 6, cut=True)
self._add_box(3.96 + 5/2, 18.45 + 6/2, 0 + 6/2, 5, 6, 6, cut=True)
self._add_box(-3.96 + 6/2, 18.45 + 5/2, 0 + 6/2, 6, 5, 6, cut=True)
self._add_box(0, 20, 0.5, 11, 11, 11, cut=True)
self._add_box(2 + 8/2, 14 + 13/2, -1 + 6/2, 8, 13, 6, cut=True)
self._add_box(-9.88 + 8/2, 15.21 + 13/2, -1 + 6/2, 8, 13, 6, cut=True)
# outer edge cuts
self._add_box(-18.0 + 11/2, 32 + 11/2, -1 + 11/2, 11, 11, 11, cut=True)
self._add_box(18 + 11/2, 32 + 11/2, -1 + 11/2, 11, 11, 11, cut=True)
# heatbed terminal screw pockets
self._add_cyl(8.5, 7.5, 0, 3.25, 8.6, cut=True)
self._add_cyl(-8.5, 7.5, 0, 3.25, 8.6, cut=True)
# clip nut pockets (m3_head approx)
self._add_cyl(11, 30, 0, 3.15, 4, cut=True)
self._add_cyl(-11, 30, 0, 3.15, 4, cut=True)
# hold screw
self._add_cyl(0, 7.5, 0, 3.15, 4, cut=True)
# LED window
self._add_box(-2.5 + 5/2, -1 + 3.5/2, -4 + 10/2, 5, 3.5, 10, cut=True)
# chamfer edges
self._add_box(-20 + 40/2, 0 + 5/2, 6.5 + 5/2, 40, 5, 5, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = HeatbedCableCover()
show(part)

View File

@ -0,0 +1,73 @@
"""Auto-converted from lcd-supports.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class LcdSupports(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === Left LCD support (support() at origin) ===
# base block: translate([-55,-2,0]) cube([69,81,10])
self._add_box(-55 + 69/2, -2 + 81/2, 0 + 10/2, 69, 81, 10)
# screw block: translate([-72,22,0]) cube([30,16,10])
self._add_box(-72 + 30/2, 22 + 16/2, 0 + 10/2, 30, 16, 10)
# outer shape cuts
self._add_box(-69.6 + 60/2, 32 + 53/2, -1 + 15/2, 60, 53, 15, cut=True)
self._add_box(13.7 + 60/2, 89.7 + 42/2, -1 + 15/2, 60, 42, 15, cut=True)
self._add_box(-19 + 60/2, -9 + 9/2, -1 + 15/2, 60, 9, 15, cut=True)
self._add_box(7 + 60/2, -3 + 68/2, -1 + 16/2, 60, 68, 16, cut=True)
self._add_box(-16 + 60/2, 60 + 50/2, -1 + 15/2, 60, 50, 15, cut=True)
self._add_box(-41 + 60/2, -45 + 80/2, -1 + 13/2, 60, 80, 13, cut=True)
# pcb cutouts
self._add_box(4 + 1.8/2, 1.5 + 56.5/2, -1 + 17/2, 1.8, 56.5, 17, cut=True)
self._add_box(0 + 5.8/2, 7.5 + 44.5/2, -1 + 17/2, 5.8, 44.5, 17, cut=True)
self._add_box(4.8 + 5.8/2, 3.5 + 52.5/2, -1 + 17/2, 5.8, 52.5, 17, cut=True)
# lower angled cuts
self._add_box(-75 + 20/2, -2 + 14/2, -1 + 15/2, 20, 14, 15, cut=True)
self._add_box(-70 + 20/2, -2 + 14/2, -1 + 15/2, 20, 14, 15, cut=True)
self._add_box(-50 + 20/2, -16.3 + 20/2, -1 + 15/2, 20, 20, 15, cut=True)
self._add_box(-76.5 + 15/2, -2 + 40/2, -1 + 15/2, 15, 40, 15, cut=True)
# screw holes (lying along X-axis — approx as horizontal boxes)
self._add_box(-71 + 22/2, 22, 5, 22, 1.75*2, 1.75*2, cut=True)
self._add_box(-70 + 22/2, 33, 5, 22, 1.75*2, 1.75*2, cut=True)
# nut traps
self._add_box(-58 + 2.2/2, 19.1 + 5.8/2, 5 - 2.8 + 29.7/2, 2.2, 5.8, 29.7, cut=True)
self._add_box(-58 + 2.2/2, 30.1 + 5.8/2, 5 - 2.8 + 29.7/2, 2.2, 5.8, 29.7, cut=True)
# === Right support (rotate 180, translate [-60,-2,0]) ===
# Mirror by adding a second support block offset
self._add_box(-60 + 55 + 69/2, -2 + 81/2, 0 + 10/2, 69, 81, 10)
self._add_box(-60 + 72 - 30/2, 22 + 16/2, 0 + 10/2, 30, 16, 10)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = LcdSupports()
show(part)

View File

@ -0,0 +1,55 @@
"""Auto-converted from polyholes.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
import math
# === SCAD constants reproduced verbatim ===
def sides(r):
return max(round(4 * r), 3)
def corrected_radius(r, n):
return 0.1 + r / math.cos(math.pi / n)
def corrected_diameter(d):
n = sides(d / 2)
return 0.2 + d / math.cos(math.pi / n)
# Default demo: poly_cylinder r=5, h=10
DEMO_R = 5
DEMO_H = 10
class Polyholes(Part):
def __init__(self, r=DEMO_R, h=DEMO_H):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
n = sides(r)
cr = corrected_radius(r, n)
# polyCylinder: cylinder with corrected radius
self._add_cyl(0, 0, 0, cr, h)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = Polyholes()
show(part)

View File

@ -0,0 +1,62 @@
"""Auto-converted from print-fan-support.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class PrintFanSupport(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# union bodies
# translate([-4,-47,23]) cylinder(h=5, r=5)
self._add_cyl(-4, -47, 23, 5, 5)
# translate([-2,-57,23]) cube([5,15,30])
self._add_box(-2 + 5/2, -57 + 15/2, 23 + 30/2, 5, 15, 30)
# translate([-5,-52,23]) cube([8,10,5])
self._add_box(-5 + 8/2, -52 + 10/2, 23 + 5/2, 8, 10, 5)
# translate([-5,-48,45]) rotate([48,0,0]) cylinder(h=10,r=6,$fn=6) — angled hex, approx vertical
self._add_cyl(-5, -48, 45, 6, 10)
# cuts
# screw hole along angled axis — approx vertical
self._add_cyl(-5, -48, 45, 1.65, 30, cut=True)
# screw head pocket
self._add_cyl(-5, -48, 45, 3.1, 6, cut=True)
# lower screw
self._add_cyl(-5, -47, 10, 1.65, 25, cut=True)
self._add_cyl(-5, -47, 27, 3.1, 1.1, cut=True)
# large shape cuts
self._add_box(10 + 60/2, -85 + 50/2, 15 + 20/2, 60, 50, 20, cut=True)
self._add_box(-15 + 50/2, -71 + 20/2, 15 + 40/2, 50, 20, 40, cut=True)
self._add_box(-15 + 50/2, -41 + 20/2, 15 + 40/2, 50, 20, 40, cut=True)
self._add_box(-15 + 20/2, -39.5 + 20/2, 44 + 20/2, 20, 20, 20, cut=True)
self._add_box(-15 + 20/2, -60 + 20/2, 52.5 + 20/2, 20, 20, 20, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = PrintFanSupport()
show(part)

View File

@ -0,0 +1,114 @@
"""Auto-converted from x-carriage-back.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class XCarriageBack(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === x_carriage_back() base ===
self._add_box(-16 + 33/2, -40.0 + 73/2, 15.1 + 8/2, 33, 73, 8)
self._add_box(-25.5 + 52/2, 4 + 30.5/2, 15.1 + 8/2, 52, 30.5, 8)
# === cuts ===
# lower bearing cut
self._add_box(-17 + 35/2, -22 + 4/2, 7.5 + 10/2, 35, 4, 10, cut=True)
# cables opening
self._add_box(-4.5 + 10/2, -18 + 4/2, 15 + 10/2, 10, 4, 10, cut=True)
self._add_cyl(0.5, -18, 10, 5, 32, cut=True)
self._add_cyl(0.5, -14, 10, 5, 32, cut=True)
self._add_box(-20 + 50/2, -19.5 + 7.5/2, 9 + 10/2, 50, 7.5, 10, cut=True)
# bearing holes (along X — approx as horizontal box cuts)
self._add_box(-15 + 31/2, -25, 11.75, 31, 7.6*2, 7.6*2, cut=True)
self._add_box(-30 + 60/2, 20, 11.75, 60, 7.6*2, 7.6*2, cut=True)
# bearing retainer slots
self._add_box(-15 + 30/2, -25 - 2 + 4/2, 18 + 2/2, 30, 4, 2, cut=True)
self._add_box(-30 + 60/2, 20 - 2 + 4/2, 18 + 2/2, 60, 4, 2, cut=True)
# hold together screws
self._add_cyl(-5, -36, 10, 1.65, 50, cut=True)
self._add_cyl(1, 4, 10, 1.65, 50, cut=True)
self._add_cyl(13, 31, 10, 1.65, 50, cut=True)
self._add_cyl(-10.5, 31, 10, 1.65, 50, cut=True)
self._add_cyl(13, 31, 19, 3.1, 50, cut=True)
self._add_cyl(-10.5, 31, 19, 3.1, 50, cut=True)
# lower screw heads
self._add_cyl(-5, -36, 19, 3.1, 6, cut=True)
self._add_box(-8.1 + 6.2/2, -46 + 10/2, 18 + 10/2, 6.2, 10, 10, cut=True)
# center screw head
self._add_cyl(1, 4, 18, 3.1, 7, cut=True)
# heat cable cuts
self._add_cyl(10.15, -37, 4, 3, 40, cut=True)
self._add_box(10.15 - 3, -37 - 10, 4 + 40/2, 6, 10, 40, cut=True)
self._add_cyl(5.85, -37, 4, 3, 40, cut=True)
self._add_box(5.85 - 3, -37 - 10, 4 + 40/2, 6, 10, 40, cut=True)
# cable holder screw (along Y)
self._add_cyl(0.5, -27, 11, 1.6, 40, cut=True)
# x-carriage screw in belt holders
self._add_cyl(-11.5, -0.5, 10, 3, 40, cut=True)
# side panel cuts
self._add_box(28 + 22/2, -4 + 10/2, 10 + 15/2, 22, 10, 15, cut=True)
self._add_box(-4 + 22/2, -4 + 10/2, 10 + 15/2, 22, 10, 15, cut=True)
# corner edge cuts
self._add_box(-20.8 + 10/2, -47.1 + 10/2, 10 + 15/2, 10, 10, 15, cut=True)
self._add_box(21.8 + 10/2, -47.1 + 10/2, 10 + 15/2, 10, 10, 15, cut=True)
self._add_box(-24.4 + 14/2, 15.2 + 10/2, 10 + 15/2, 14, 10, 15, cut=True)
self._add_box(26.9 + 10/2, 15.2 + 14/2, 10 + 15/2, 10, 14, 15, cut=True)
self._add_box(-19.55 + 10/2, 28 + 10/2, 10 + 15/2, 10, 10, 15, cut=True)
self._add_box(22.05 + 10/2, 28 + 10/2, 10 + 15/2, 10, 10, 15, cut=True)
# top edge cuts
self._add_box(-22 + 44/2, 35 + 10/2, 21 + 10/2, 44, 10, 10, cut=True)
# upper side cuts
self._add_box(17 + 10/2, 25 + 10/2, 10 + 15/2, 10, 10, 15, cut=True)
self._add_box(-29.5 + 15/2, 25 + 15/2, 10 + 15/2, 15, 15, 15, cut=True)
# side edge cuts
self._add_box(27 + 10/2, -20 + 50/2, 16 + 10/2, 10, 50, 10, cut=True)
self._add_box(-34.2 + 10/2, -20 + 50/2, 21 + 10/2, 10, 50, 10, cut=True)
# ziptie cutouts (approx as cylinders)
self._add_cyl(-21.5 + 1, 20, 12, 8.5, 4, cut=True)
self._add_cyl(19 + 0.5, 20, 12, 8.5, 4, cut=True)
# upper corner cleanup
self._add_box(-20.8 + 50/2, -40.5 + 20/2, 16 + 10/2, 50, 20, 10, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = XCarriageBack()
show(part)

View File

@ -0,0 +1,149 @@
"""Auto-converted from x-carriage.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
# Bearing constants (from bearing.scad)
bearing_diameter = 14.95
thinwall = 3
bearing_size = bearing_diameter + 2 * thinwall
class XCarriage(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === x_carriage_base() ===
# Small bearing holder at x=-33/2, y=0 (horizontal, 1 bearing)
# horizontal_bearing_base(1): cube([24, 8+25, 12]) at z=6
self._add_box(-33/2, 0, 6, 24, 33, 12)
# Long bearing holder at x=-33/2, y=45 (2 bearings)
# horizontal_bearing_base(2): cube([24, 8+50, 12]) at z=6
self._add_box(-33/2, 45, 6, 24, 58, 12)
# Base plate
self._add_box(-34 + 34.5/2, -14 + 70.5/2, 0 + 7/2, 34.5, 70.5, 7)
self._add_box(-34 + 35/2, -15 + 7/2, 0 + 15/2, 35, 7, 15)
self._add_box(-42.5 + 52/2, 53.0 + 6.5/2, 0 + 15/2, 52, 6.5, 15)
# Upper motor screw block
self._add_box(-34 + 43.5/2, 56.8 + 19.7/2, 0 + 8/2, 43.5, 19.7, 8)
# Belt holder base
self._add_box(-42.5 + 52/2, 20 + 16/2, 0 + 7/2, 52, 16, 7)
self._add_box(-42.5 + 52/2, 18 + 16.3/2, 7 + 8/2, 52, 16.3, 8)
# cable tray blocks
self._add_box(-21 + 9/2, 23 + 12/2, 0 + 15/2, 9, 12, 15)
self._add_box(6.5 + 3/2, 32 + 5/2, 10 + 5/2, 3, 5, 5)
self._add_box(-42.5 + 4/2, 32 + 5/2, 10 + 5/2, 4, 5, 5)
self._add_box(-39.9 + 9/2, 11 + 2/2, 0 + 15/2, 9, 2, 15)
self._add_box(-39.9 + 9/2, 5.5 + 2/2, 0 + 15/2, 9, 2, 15)
self._add_box(-2 + 11.45/2, 5.5 + 2/2, 0 + 15/2, 11.45, 2, 15)
self._add_box(-2 + 11.45/2, 11 + 2/2, 7 + 8/2, 11.45, 2, 8)
self._add_box(-31 + 30/2, 11.5 + 1.5/2, 7 + 8/2, 30, 1.5, 8)
self._add_box(0 + 9.5/2, 11 + 22/2, 0 + 7/2, 9.5, 22, 7)
# === bearing holes (cuts) ===
# Small bearing: horizontal_bearing_holes_nozip_smooth(1)
# Main bore (along X): cutter_length=35, r=bearing_diameter/2+0.2
self._add_cyl(-33/2, 0, 12, bearing_diameter/2 + 0.2, 35, cut=True)
# Long bearing: horizontal_bearing_holes_nozip_smooth(2)
self._add_cyl(-33/2, 45, 12, bearing_diameter/2 + 0.2, 60, cut=True)
# ziptie cutouts
self._add_cyl(2 + 0.75, 45, 12, 10.8, 3.5, cut=True)
self._add_cyl(2 + 0, 45, 12, 9, 6, cut=True)
self._add_cyl(-38 + 0.75, 45, 12, 10.8, 3.5, cut=True)
self._add_cyl(-38 + 0, 45, 12, 9, 6, cut=True)
# ziptie head cuts
self._add_box(0 + 10/2, 52.5 + 10/2, 12 + 5/2, 10, 10, 5, cut=True)
self._add_box(-45 + 13.5/2, 52.5 + 10/2, 12 + 5/2, 13.5, 10, 5, cut=True)
# Extruder mounting holes
self._add_cyl(-7, 15.5, -1, 1.65, 20, cut=True)
self._add_cyl(-27, 15.5, -1, 1.65, 20, cut=True)
self._add_cyl(-7, 15.5, 4, 3.1, 4, cut=True)
self._add_cyl(-27, 15.5, 4, 3.1, 4, cut=True)
self._add_cyl(-7, 15.5, 7, 4, 30, cut=True)
self._add_cyl(-27, 15.5, 7, 3.5, 30, cut=True)
# Carriage slimmer cuts
self._add_box(-55.5 + 3 + 10/2, 19 + 40/2, -1 + 30/2, 10, 40, 30, cut=True)
self._add_box(12.5 - 3 + 10/2, 19 + 40/2, -1 + 30/2, 10, 40, 30, cut=True)
# fancy shape cuts
self._add_box(-37 + 50/2, -12 + 8/2, -6 + 25/2, 50, 8, 25, cut=True)
self._add_box(-35 + 6/2, -19.2 + 6/2, 0 + 16/2, 6, 6, 16, cut=True)
self._add_box(2 + 6/2, -20.4 + 6/2, 0 + 16/2, 6, 6, 16, cut=True)
self._add_box(7.5 + 20/2, 59.5 + 20/2, -18 + 40/2, 20, 20, 40, cut=True)
# final_cutout cuts
# bottom back mounting screws
self._add_cyl(-22, -11, 4, 1.65, 20, cut=True)
self._add_box(-24.8 + 5.6/2, -14 + 7/2, 10 + 2.1/2, 5.6, 7, 2.1, cut=True)
# x-carriage-back mounting screws
self._add_cyl(-4, 56, 0, 1.7, 40, cut=True)
self._add_cyl(-27.5, 56, 0, 1.7, 40, cut=True)
self._add_box(-30.3 + 5.6/2, 53 + 8/2, 8 + 2/2, 5.6, 8, 2, cut=True)
self._add_box(-6.8 + 5.6/2, 53 + 8/2, 8 + 2/2, 5.6, 8, 2, cut=True)
# center mounting screw
self._add_cyl(-16, 29, 0, 1.65, 40, cut=True)
self._add_box(-18.8 + 5.6/2, 26 + 12/2, 10.5 + 2.1/2, 5.6, 12, 2.1, cut=True)
# endstop hole
self._add_cyl(-8, -11, 11, 1.4, 10, cut=True)
# motor screws (upper)
self._add_cyl(2.5, 67.5, -50, 1.8, 100, cut=True)
self._add_cyl(2.5, 67.5, 7.5, 3.2, 7, cut=True)
self._add_cyl(-28.5, 67.5, 7.5, 3.2, 20, cut=True)
self._add_cyl(-28.5, 67.5, -1, 1.65, 20, cut=True)
# hold together screws clearance
self._add_cyl(-4.5, 25.5, -1, 2.2, 10, cut=True)
self._add_cyl(-28.5, 25.5, -1, 2.2, 10, cut=True)
# belt holder pin cuts
self._add_cyl(-22.5, 30.2, 7, 1.5, 100, cut=True)
self._add_cyl(-9.6, 29.7, 7, 1.5, 100, cut=True)
# filament sensor connector slot
self._add_box(-1.5 + 1/2, 62 + 5/2, -1.3 + 5/2, 1, 5, 5, cut=True)
self._add_box(-9 + 9/2, 70.6 + 15/2, -1.3 + 15/2, 9, 15, 15, cut=True)
# motor cable opening
self._add_box(0.5 + 8/2, 10 + 18/2, -1 + 6/2, 8, 18, 6, cut=True)
# filament hole
self._add_cyl(-14.199, 9.05, 0, 1.62, 40, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = XCarriage()
show(part)

View File

@ -0,0 +1,88 @@
"""Auto-converted from x-end-idler.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
rod_distance = 45
bearing_diameter = 14.95
thinwall = 3
bearing_size = bearing_diameter + 2 * thinwall
height = 58
class XEndIdler(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === x_end_base() ===
self._add_box(-15, -9, height/2, 17, 39, height)
self._add_box(-8 + 5/2, -28.5 + 1/2, 13.5/2, 5, 1, 13.5)
# bearing holder
self._add_box(-2 - bearing_size/4, 0, 29, 4 + bearing_size/2, bearing_size, 58)
self._add_cyl(0, 0, 29, bearing_size/2, 58)
# nut trap
self._add_cyl(0, -17, 0, 12.5, 13.5)
self._add_cyl(0, -17, 13, 12.5, 3)
# === x_end_idler extra base — side wall ===
self._add_box(-6.5 + 1/2, -21 + 12.5/2, 13.5 + 42/2, 1, 12.5, 42)
# waste pockets (cuts)
self._add_cyl(-15, -1, 6, 5, 5, cut=True)
self._add_cyl(-15, -1, 51, 5, 5, cut=True)
# bearing stop ring
self._add_cyl(0, 0, 57, 8, 1)
self._add_cyl(0, 0, 56.5, 7, 2, cut=True)
# bearing spacer
self._add_cyl(0, 0, 26, 8, 6)
self._add_cyl(0, 0, 25, 7.55, 8, cut=True)
# === x_end_holes() cuts ===
# bearing bore
self._add_cyl(0, 0, 31, bearing_diameter/2 + 0.2, 62, cut=True)
# belt slot
self._add_box(-15, -10, 30, 10, 46, 28, cut=True)
# bottom rod
self._add_cyl(-15, -41, 6, 7.8/2, 50, cut=True)
# top rod
self._add_cyl(-15, -41.5, rod_distance + 6, 7.8/2, 50, cut=True)
# TR nut hole
self._add_cyl(0, -17, -1, 6.7, 14.51, cut=True)
# Pulley screw (along X, approx as horizontal cyl via box)
self._add_box(0 + 80/2, -19 + 3.5, 30.25, 80, 1.55*2, 1.55*2, cut=True)
# pulley side cut
self._add_box(-9 + 9/2, -19 + 3.5, 30.25, 9, 9.5*2, 9.5*2, cut=True)
self._add_box(-19 + 10/2, -35 + 20/2, 21.25 + 18/2, 10, 20, 18, cut=True)
# outer corner cuts
self._add_box(-25 + 30/2, 37 + 20/2, 49 + 20/2, 30, 20, 20, cut=True)
self._add_box(-47 + 20/2, -40 + 80/2, 60 + 20/2, 20, 80, 20, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = XEndIdler()
show(part)

View File

@ -0,0 +1,113 @@
"""Auto-converted from x-end-motor.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
rod_distance = 45
bearing_diameter = 14.95
thinwall = 3
bearing_size = bearing_diameter + 2 * thinwall
height = 58
class XEndMotor(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === x_end_base() ===
self._add_box(-15, -9, height/2, 17, 39, height)
self._add_box(-8 + 5/2, -28.5 + 1/2, 13.5/2, 5, 1, 13.5)
# bearing holder
self._add_box(-2 - bearing_size/4, 0, 29, 4 + bearing_size/2, bearing_size, 58)
self._add_cyl(0, 0, 29, bearing_size/2, 58)
# nut trap
self._add_cyl(0, -17, 0, 12.5, 13.5)
self._add_cyl(0, -17, 13, 12.5, 3)
# === x_end_motor_base extra: translate([-15,31,26.5]) cube([17,44,53], center) ===
self._add_box(-15, 31, 26.5, 17, 44, 53)
# === x_end_holes() (cuts) ===
# bearing bore
self._add_cyl(0, 0, 31, bearing_diameter/2 + 0.2, 62, cut=True)
# belt slot
self._add_box(-15, -10, 30, 10, 46, 28, cut=True)
# bottom rod
self._add_cyl(-15, -41, 6, 7.8/2, 50, cut=True)
# top rod
self._add_cyl(-15, -41.5, rod_distance + 6, 7.8/2, 50, cut=True)
# TR nut hole
self._add_cyl(0, -17, -1, 6.7, 14.51, cut=True)
# === x_end_motor_holes() ===
# Belt hole: translate([-20,-21+32,-12+30]) cube([10,25,22]) => approx
self._add_box(-20 + 10/2, 11 + 25/2, 18 + 22/2, 10, 25, 22, cut=True)
# Motor mounting screws (NEMA17: 31mm pattern)
for dy, dz in [(15.5, 15.5), (15.5, -15.5)]:
self._add_cyl(-1 + 32, 32 + dy, 30.25 + dz, 1.55, 30, cut=True)
self._add_cyl(-1 + 32, 32 - dy, 30.25 + dz, 1.55, 30, cut=True)
# Motor shaft opening (hex approx as cylinder)
self._add_cyl(0, 32, 30, 17, 70, cut=True)
# Material saving cutout
self._add_box(-10 + 32 + 60/2, 10 + 32 + 42/2, 12 + 30.25 + 42/2, 60, 42, 42, cut=True)
# Motor shaft details
self._add_cyl(-30, 19.05, 30, 3.5, 30)
# Waste pockets
self._add_cyl(-15, 7, 6, 5, 3.5, cut=True)
self._add_cyl(-15, 7, 51, 5, 3.5, cut=True)
# Rod contact windows
self._add_box(-17 + 4/2, 3 + 4/2, 55 + 10/2, 4, 4, 10, cut=True)
self._add_box(-17 + 4/2, 3 + 4/2, -8 + 10/2, 4, 4, 10, cut=True)
# Bearing stop
self._add_cyl(0, 0, 57, 8, 1)
self._add_cyl(0, 0, 56.5, 7, 2, cut=True)
# Bearing spacer
self._add_cyl(0, 0, 26, 8, 6)
self._add_cyl(0, 0, 25, 7.55, 8, cut=True)
# Belt tensioner body (approx as boxes)
self._add_cyl(-24, 9, 30.25, 4, 27)
self._add_box(-24, -18, 30.25, 10, 10.5, 10)
# Belt tensioner cuts
self._add_cyl(-24, 32 - 15.5 - 2.5, 30.25, 1.6, 35, cut=True)
self._add_cyl(-24, 32 - 15.5 - 4.5 - 30, 30.25, 3.2, 30, cut=True)
# corner cleanup cuts
self._add_box(-47 + 20/2, -40 + 80/2, 60 + 20/2, 20, 80, 20, cut=True)
self._add_box(-25 + 30/2, -37 + 20/2, 49 + 20/2, 30, 20, 20, cut=True)
self._add_box(-25 + 30/2, 23.5 + 20/2, 49 + 20/2, 30, 20, 20, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = XEndMotor()
show(part)

View File

@ -0,0 +1,78 @@
"""Auto-converted from x-end.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
# === SCAD constants reproduced verbatim ===
rod_distance = 45
bearing_diameter = 14.95
thinwall = 3
bearing_size = bearing_diameter + 2 * thinwall
class XEnd(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === x_end_base() ===
# Main block: translate([-15,-9,height/2]) cube([17,39,58], center=true)
height = 58
self._add_box(-15, -9, height/2, 17, 39, height)
self._add_box(-8 + 5/2, -28.5 + 1/2, 13.5/2, 5, 1, 13.5)
# Vertical bearing base
self._add_box(-2 - bearing_size/4, 0, 29, 4 + bearing_size/2, bearing_size, 58)
self._add_cyl(0, 0, 29, bearing_size/2, 58)
# Nut trap cylinder
self._add_cyl(0, -17, 0, 12.5, 13.5)
self._add_cyl(0, -17, 13, 12.5, 3)
# === x_end_holes() (cuts) ===
# Vertical bearing bore
self._add_cyl(0, 0, 31, bearing_diameter/2 + 0.2, 62, cut=True)
# Belt stress relief slot
self._add_box(-15, -10, 30, 10, 46, 28, cut=True)
# Bottom pushfit rod hole
self._add_cyl(-15, -41, 6, 7.8/2, 50, cut=True)
# Top pushfit rod hole
self._add_cyl(-15, -41.5, rod_distance + 6, 7.8/2, 50, cut=True)
# TR Nut hole
self._add_cyl(0, -17, -1, 6.7, 14.51, cut=True)
# Screw holes for TR nut (approx positions)
self._add_cyl(0 + 9.5 * 0.707, -17 - 9.5 * 0.707, -4, 1.65, 19, cut=True)
self._add_cyl(0 - 9.5 * 0.707, -17 + 9.5 * 0.707, -4, 1.65, 19, cut=True)
# Nut traps (hex approx as cylinders)
self._add_cyl(0 + 9.5 * 0.707, -17 - 9.5 * 0.707, 11, 3.15, 6, cut=True)
self._add_cyl(0 - 9.5 * 0.707, -17 + 9.5 * 0.707, 10, 3.1, 3, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = XEnd()
show(part)

View File

@ -0,0 +1,80 @@
"""Auto-converted from z-axis-bottom.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
MX = 25 + 4.3 # motor centre X
MY = 20 # motor centre Y
class ZAxisBottom(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === z_bottom_base() ===
# plate touching base (right version, mirrors handled by approx)
self._add_box(0 + 7.5/2, -1.5 + 49/2, 0 + 36/2, 7.5, 49, 36)
self._add_box(0 + 30/2, -5 + 3.7/2, 0 + 22/2, 30, 3.7, 22)
self._add_box(0 + 30/2, 42 + 5.5/2, 0 + 22/2, 30, 5.5, 22)
self._add_box(0 + 50/2, -5 + 52.5/2, 0 + 7/2, 50, 52.5, 7)
# === z_bottom_holes() (cuts) ===
# Frame screw holes along X
self._add_box(-1 + 20/2, 10, 12, 20, 1.6*2, 1.6*2, cut=True)
self._add_box(-1 + 20/2, 30, 12, 20, 1.6*2, 1.6*2, cut=True)
self._add_box(-1 + 20/2, 20, 32, 20, 1.6*2, 1.6*2, cut=True)
# Screw head holes
self._add_box(4 + 20/2, 10, 12, 20, 3.1*2, 3.1*2, cut=True)
self._add_box(4 + 20/2, 30, 12, 20, 3.1*2, 3.1*2, cut=True)
self._add_box(4 + 20/2, 20, 32, 20, 3.1*2, 3.1*2, cut=True)
# Z rod holder
self._add_cyl(MX, 3, -0.1, 4.05, 5.6, cut=True)
self._add_cone(MX, 3, -2.1, 6, 4, 2.6) # chamfer
self._add_box(MX - 1 + 2/2, 3 + 10/2, 0.5 + 8/2, 2, 10, 8, cut=True)
# Motor mounting screws (4 corners of 31x31mm NEMA17 pattern)
for dx, dy in [(15.5, 15.5), (15.5, -15.5), (-15.5, 15.5), (-15.5, -15.5)]:
self._add_cyl(MX + dx, MY + dy, -2, 1.65, 20, cut=True)
self._add_cone(MX + dx, MY + dy, -0.5, 4.5, 3.2, 2) # countersink
# Motor centre opening
self._add_cyl(MX, MY, -1, 11.2, 20, cut=True)
self._add_cone(MX, MY, 0, 12, 11.2, 2)
# === corner/fancy shape approx (large cuts to shape outer profile) ===
self._add_box(-38 + 30/2, -10 + 60/2, -2 + 30/2, 30, 60, 30, cut=True)
self._add_box(47 + 30/2, -10 + 60/2, -2 + 30/2, 30, 60, 30, cut=True)
self._add_box(8 + 30/2, 0 + 50/2, 38 + 30/2, 30, 50, 30, cut=True)
# left variant: mirror offset (placed adjacent, approx)
self._add_box(70 + 7.5/2, -1.5 + 49/2, 0 + 36/2, 7.5, 49, 36)
self._add_box(70 + 30/2, -5 + 3.7/2, 0 + 22/2, 30, 3.7, 22)
self._add_box(70 + 50/2, -5 + 52.5/2, 0 + 7/2, 50, 52.5, 7)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = ZAxisBottom()
show(part)

View File

@ -0,0 +1,82 @@
"""Auto-converted from z-axis-top.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
MX = 25 + 4.3 # rod/screw centre X
MY = 3.0 # rod centre Y
class ZAxisTop(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# === z_top_base() ===
self._add_box(0 + 8/2, -5 + 45/2, 0 + 16/2, 8, 45, 16)
self._add_box(0 + 33/2, -5 + 3.6/2, 0 + 12/2, 33, 3.6, 12)
self._add_box(0 + 38/2, -5 + 45/2, 0 + 5/2, 38, 45, 5)
# rod boss
self._add_cyl(MX, MY + 0.2, 5, 7, 2.5)
# === z_top_holes() (cuts) ===
# Screw holes (along X)
self._add_box(-1 + 20/2, 10, 10, 20, 1.6*2, 1.6*2, cut=True)
self._add_box(-1 + 20/2, 30, 10, 20, 1.6*2, 1.6*2, cut=True)
# Screw heads
self._add_box(4 + 20/2, 10, 10, 20, 3.1*2, 3.1*2, cut=True)
self._add_box(4 + 10/2, 10 - 3.1, 10 + 10/2, 10, 6.2, 10, cut=True)
self._add_box(4 + 20/2, 30, 10, 20, 3.1*2, 3.1*2, cut=True)
self._add_box(4 + 10/2, 30 - 3.1, 10 + 10/2, 10, 6.2, 10, cut=True)
# Z rod holder
self._add_cyl(MX, MY, 0.6, 4.05, 50, cut=True)
self._add_cone(MX, MY, 3.4, 4.05, 4.3, 4.2) # taper (not cut)
# Material saving hex cutouts
self._add_cyl(16, 10, -4, 8, 50, cut=True)
self._add_cyl(16, 28, -4, 8, 50, cut=True)
# Z screw hole (leadscrew nut pocket)
self._add_cyl(MX, MY + 17, 0.6, 5.8, 50, cut=True)
# Rod slot
self._add_box(MX - 1 + 2/2, MY + 15/2, 0.6 + 8/2, 2, 15, 8, cut=True)
# Shape cuts (outer profile)
self._add_box(4 + 30/2, -1 - 5 + 50/2, 12 + 30/2, 30, 50, 30, cut=True)
self._add_box(8 + 50/2, 28 + 50/2, -3 + 51/2, 50, 50, 51, cut=True)
# left variant (mirrored, offset)
self._add_box(60 + 8/2, -5 + 45/2, 0 + 16/2, 8, 45, 16)
self._add_box(60 + 33/2, -5 + 3.6/2, 0 + 12/2, 33, 3.6, 12)
self._add_box(60 + 38/2, -5 + 45/2, 0 + 5/2, 38, 45, 5)
self._add_cyl(60 + MX, MY + 0.2, 5, 7, 2.5)
self._add_cyl(60 + MX, MY, 0.6, 4.05, 50, cut=True)
self._add_cyl(60 + MX, MY + 17, 0.6, 5.8, 50, cut=True)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = ZAxisTop()
show(part)

View File

@ -0,0 +1,62 @@
"""Auto-converted from z-screw-cover.scad — cadbuildr.foundation port."""
from cadbuildr.foundation import (
Part, Sketch, Point,
Square, Rectangle, Circle, RegularPolygon, RectangleRounded,
Extrusion, Lathe, Hole,
Cylinder, Box, Sphere, Cone,
show,
)
class ZScrewCover(Part):
def __init__(self):
super().__init__()
sketch = self._sketch = Sketch(self.xy())
# Main body: cone from r=8 to r=4.6 over h=4 starting at z=1
self._add_cone(0, 0, 1, 8, 4.6, 4)
# Base disk r=8, h=1
self._add_cyl(0, 0, 0, 8, 1)
# Central bore cut: cylinder r=4.2, h=7 starting at z=-1
self._add_cyl(0, 0, -1, 4.2, 7, cut=True)
# Entry chamfer cut: cone r1=4.5 r2=4.2, h=1
self._add_cone(0, 0, 0, 4.5, 4.2, 1) # forms chamfer shape (not a cut here)
# Decorative fins (small cones along X/Y axes, approximated as small cylinders)
# Layer 1 z=4.3
self._add_cyl(-4.2, 0, 4.3, 0.5, 1)
self._add_cyl(4.2, 0, 4.3, 0.5, 1)
self._add_cyl(0, 4.2, 4.3, 0.5, 1)
self._add_cyl(0, -4.2, 4.3, 0.5, 1)
# Layer 2 z=4.0
self._add_cyl(-4.2, 0.5, 4.0, 0.45, 0.8)
self._add_cyl(4.2, -0.5, 4.0, 0.45, 0.8)
self._add_cyl(0.5, 4.2, 4.0, 0.45, 0.8)
self._add_cyl(-0.5, -4.2, 4.0, 0.45, 0.8)
# Layer 3 z=3.7
self._add_cyl(-4.2, 1, 3.7, 0.4, 0.6)
self._add_cyl(4.2, -1, 3.7, 0.4, 0.6)
self._add_cyl(1, 4.2, 3.7, 0.4, 0.6)
self._add_cyl(-1, -4.2, 3.7, 0.4, 0.6)
def _pt(self, x, y):
return Point(self._sketch, x, y)
def _add_box(self, x, y, z, w, d, h, cut=False):
self.add_operation(Box(self._pt(x, y), w, d, h, cut=cut))
def _add_cyl(self, x, y, z, radius, height, cut=False):
self.add_operation(Cylinder(self._pt(x, y), radius, height, cut=cut))
def _add_cone(self, x, y, z, r1, r2, height):
self.add_operation(Cone(self._pt(x, y), r1, r2, height))
def _add_sphere(self, x, y, z, radius, cut=False):
self.add_operation(Sphere(self._pt(x, y), radius, cut=cut))
def _add_extrusion(self, shape, end, start=0, cut=False):
self.add_operation(Extrusion(shape, end=end, start=start, cut=cut))
part = ZScrewCover()
show(part)