103 lines
3.3 KiB
Python
103 lines
3.3 KiB
Python
import FreeCAD as App
|
|
import FreeCADGui
|
|
import FreeCAD
|
|
import Part
|
|
import math
|
|
|
|
class Lego:
|
|
def __init__(self,obj, unitsX=4, unitsY=2,unitsZ=1,modifier=1):
|
|
obj.addProperty("App::PropertyInteger","unitsX","Lego","Size in knobs in X direction.").unitsX = unitsX
|
|
obj.addProperty("App::PropertyInteger","unitsY","Lego","Size in knobs in Y direction.").unitsY = unitsY
|
|
obj.addProperty("App::PropertyInteger","unitsZ","Lego","Size in knobs in Z direction.").unitsZ = unitsZ
|
|
obj.addProperty("App::PropertyInteger","modifier","Lego","Variant No ").modifier = modifier
|
|
obj.Proxy = self
|
|
|
|
def execute(self, fp):
|
|
'''Print a short message when doing a recomputation, this method is mandatory'''
|
|
fp.Shape = Lego.buildshape(fp.unitsX, fp.unitsY, fp.unitsZ, fp.modifier)
|
|
|
|
@staticmethod
|
|
def buildshape( unitsX, unitsY, unitsZ, modifier):
|
|
gap=0.1
|
|
gaps=2*gap
|
|
unitSize = 8
|
|
height_U=3.2 # 9.6
|
|
knobHeight=1.8
|
|
knobRadius=4.9/2
|
|
wall=1.35 # 1.5 guessed
|
|
upWall=1.2 # 5.5 guessed
|
|
supportthickness=0.6 # 0.15x4 or 0.20x3
|
|
maxsupportlayerthickness=0.15
|
|
supportdistance=4 # 4x4=16mm^2, printer option
|
|
cylRadius = (unitSize*math.sqrt(2)-2*knobRadius)/2 #0000003,2568542494923801952067548968388
|
|
#cylWall = round(3.25685,5)
|
|
cylWall = 0.8
|
|
|
|
# box
|
|
l=unitSize*unitsX-gaps
|
|
w=unitSize*unitsY-gaps
|
|
height=height_U*unitsZ
|
|
c1=Part.makeBox(l, w, height,FreeCAD.Vector(-l/2.0,-w/2.0,0))
|
|
c2=Part.makeBox(l-gaps-2*wall, w-gaps-2*wall, height,FreeCAD.Vector(-(l-gaps-2*wall)/2.0,-(w-gaps-2*wall)/2.0,-1*upWall))
|
|
d1=c1.cut(c2)
|
|
shape1=d1
|
|
|
|
# knobs
|
|
knobs=Part.Shape()
|
|
knob=Part.makeCylinder(knobRadius,knobHeight+upWall/2,FreeCAD.Vector(0,0,height-upWall/2.0))
|
|
for x in range(unitsX):
|
|
for y in range(unitsY):
|
|
newknob=knob.copy()
|
|
newknob.translate((x*unitSize, y*unitSize, 0))
|
|
if knobs.isNull():
|
|
knobs=newknob
|
|
else:
|
|
knobs=knobs.fuse(newknob)
|
|
knobs.translate(((1-unitsX)*unitSize/2, (1-unitsY)*unitSize/2, 0))
|
|
|
|
# Cylinder
|
|
if ((unitsX > 1) and (unitsY > 1)):
|
|
cyl=Part.makeCylinder(cylRadius,height-upWall/2).cut(Part.makeCylinder(cylRadius-cylWall,height))
|
|
cyl.translate((0,0,0))#upWall/8))
|
|
cyls=Part.Shape()
|
|
for x in range(unitsX-1):
|
|
for y in range(unitsY-1):
|
|
newcyl=cyl.copy()
|
|
newcyl.translate((x*unitSize, y*unitSize, 0))
|
|
if cyls.isNull():
|
|
cyls=newcyl
|
|
else:
|
|
cyls=cyls.fuse(newcyl)
|
|
cyls.translate(((2-unitsX)*unitSize/2, (2-unitsY)*unitSize/2, 0))
|
|
|
|
# Modifier bits:
|
|
# 0.. 0: flat; 1: with knobs
|
|
# 1.. 0: flat; 1: with cylinders on the bottom site
|
|
# 2.. 0:
|
|
# 3.. 0:
|
|
# 4.. 0:
|
|
# 5.. 0:
|
|
# 6.. 0:
|
|
# 7.. 0:
|
|
|
|
if (modifier & 1) == 0: # Without knobs
|
|
pass
|
|
|
|
if (modifier & 1) == 1: # With knobs
|
|
newknobs=knobs.copy()
|
|
#newknobs.translate((0,0,0))
|
|
shape1=shape1.fuse(newknobs)
|
|
|
|
if (modifier & 2) == 0:
|
|
pass
|
|
|
|
if (modifier & 2) == 2:
|
|
shape1=shape1.fuse(cyls)
|
|
|
|
return shape1
|
|
|
|
a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Lego")
|
|
Lego(a)
|
|
a.ViewObject.Proxy=0 # just set it to something different from None (this assignment is needed to run an internal notification)
|
|
FreeCAD.ActiveDocument.recompute()
|