Skip to content

Instantly share code, notes, and snippets.

@trygvis
Created May 2, 2016 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trygvis/0a997b1afb47e5e00919240ee4b71239 to your computer and use it in GitHub Desktop.
Save trygvis/0a997b1afb47e5e00919240ee4b71239 to your computer and use it in GitHub Desktop.
Macro for FreeCAD to create boxes suitable for laser cutting
# Macro for FreeCAD to create boxes suitable for laser cutting
from FreeCAD import Base, Vector, Matrix
import Part
class BoxCfg:
def __init__(self, thickness, notches):
self.thickness = thickness
self.notches = notches
self.piece_size = 60
class VGen:
def __init__(self, current, dir):
if dir == 'right':
self.x_x = 1
self.x_y = 0
self.y_x = 0
self.y_y = 1
elif dir == 'left':
self.x_x = -1
self.x_y = 0
self.y_x = 0
self.y_y = -1
elif dir == 'down':
self.x_x = 0
self.x_y = -1
self.y_x = 1
self.y_y = 0
elif dir == 'up':
self.x_x = 0
self.x_y = 1
self.y_x = -1
self.y_y = 0
else:
raise Exception('Bad dir: ' + dir)
self.current = current
self.list = []
def move(self, x, y, z):
self.current = self.current.add(Vector(x, y, z))
self.list.append(self.current)
def moveX(self, value):
self.move(self.x_x * value, self.x_y * value, 0)
def moveY(self, value):
self.move(self.y_x * value, self.y_y * value, 0)
def line1(cfg, start, dir, inv, include_start):
x = 10
if inv:
inv = -1
else:
inv = 1
g = VGen(start, dir)
if include_start:
g.moveX(cfg.thickness)
g.moveX(x)
for i in range(0, cfg.notches):
g.moveY(-cfg.thickness * inv)
g.moveX(x)
g.moveY(cfg.thickness * inv)
g.moveX(x)
if include_start:
g.moveX(cfg.thickness)
return g.list
def largePolygon(cfg):
v = [Vector(0, 0, 0)]
top = line1(cfg, v[-1], 'right', False, True); v.extend(top)
left = line1(cfg, v[-1], 'down', False, True); v.extend(left)
bottom = line1(cfg, v[-1], 'left', False, True); v.extend(bottom)
right = line1(cfg, v[-1], 'up', False, True); v.extend(right)
return v
def mediumPolygon(cfg):
v = [Vector(cfg.thickness, 0, 0)]
top = line1(cfg, v[-1], 'right', False, False); v.extend(top)
left = line1(cfg, v[-1], 'down', True, True); v.extend(left)
bottom = line1(cfg, v[-1], 'left', False, False); v.extend(bottom)
right = line1(cfg, v[-1], 'up', True, True); v.extend(right)
return v
def smallPolygon(cfg):
v = [Vector(cfg.thickness, 0, 0)]
top = line1(cfg, v[-1], 'right', True, False); v.extend(top)
left = line1(cfg, v[-1], 'down', True, False); v.extend(left)
bottom = line1(cfg, v[-1], 'left', True, False); v.extend(bottom)
right = line1(cfg, v[-1], 'up', True, False); v.extend(right)
return v
print("------------------------------------")
doc = FreeCAD.newDocument()
doc.saveAs("/tmp/foo.fcstd")
# front back left
# right top bottom
cfg = BoxCfg(3, 2)
m = Matrix()
m.move(cfg.piece_size * -0.5, 0, 0)
s = Part.makePolygon(largePolygon(cfg))
s.transformShape(m)
FreeCAD.ActiveDocument.addObject("Part::Feature", "Front").Shape = s
m = Matrix()
m.move(cfg.piece_size * 0.5, 0, 0)
s = Part.makePolygon(largePolygon(cfg))
s.transformShape(m)
FreeCAD.ActiveDocument.addObject("Part::Feature", "Back").Shape = s
m = Matrix()
m.move(cfg.piece_size * 1.5, 0, 0)
l = Part.makePolygon(mediumPolygon(cfg))
l.transformShape(m)
FreeCAD.ActiveDocument.addObject("Part::Feature", "Left").Shape = l
m = Matrix()
m.move(cfg.piece_size * -0.5, cfg.piece_size * -1, 0)
l = Part.makePolygon(smallPolygon(cfg))
l.transformShape(m)
FreeCAD.ActiveDocument.addObject("Part::Feature", "Right").Shape = l
m = Matrix()
m.move(cfg.piece_size * 0.5, cfg.piece_size * -1, 0)
l = Part.makePolygon(smallPolygon(cfg))
l.transformShape(m)
FreeCAD.ActiveDocument.addObject("Part::Feature", "Top").Shape = l
m = Matrix()
m.move(cfg.piece_size * 1.5, cfg.piece_size * -1, 0)
l = Part.makePolygon(mediumPolygon(cfg))
l.transformShape(m)
FreeCAD.ActiveDocument.addObject("Part::Feature", "Bottom").Shape = l
Gui.ActiveDocument = doc
Gui.SendMsgToActiveView("ViewFit")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment