Added pear shaped mounting hole drawing function (#392)
and add them to BinTray and TrafficLight Add labels to the parts of these generators Add doc strings to all hole types
This commit is contained in:
parent
88ea5f8385
commit
1bb4b8c0c3
|
@ -1237,6 +1237,17 @@ class Boxes:
|
||||||
@restore
|
@restore
|
||||||
@holeCol
|
@holeCol
|
||||||
def dHole(self, x, y, r=None, d=None, w=None, rel_w=0.75, angle=0):
|
def dHole(self, x, y, r=None, d=None, w=None, rel_w=0.75, angle=0):
|
||||||
|
"""
|
||||||
|
Draw a hole for a shaft with flat edge - D shaped hole
|
||||||
|
:param x: center position
|
||||||
|
:param y: center position
|
||||||
|
:param r: radius (overrides d)
|
||||||
|
:param d: diameter
|
||||||
|
:param w: width measured against flat side in mm
|
||||||
|
:param rel_w: width in percent
|
||||||
|
:param angle: orentation (rotation) of the flat side
|
||||||
|
"""
|
||||||
|
|
||||||
if r is None:
|
if r is None:
|
||||||
r = d / 2.0
|
r = d / 2.0
|
||||||
if w is None:
|
if w is None:
|
||||||
|
@ -1257,6 +1268,18 @@ class Boxes:
|
||||||
@restore
|
@restore
|
||||||
@holeCol
|
@holeCol
|
||||||
def flatHole(self, x, y, r=None, d=None, w=None, rel_w=0.75, angle=0):
|
def flatHole(self, x, y, r=None, d=None, w=None, rel_w=0.75, angle=0):
|
||||||
|
"""
|
||||||
|
Draw a hole for a shaft with two opposed flat edges - ( ) shaped hole
|
||||||
|
:param x: center position
|
||||||
|
:param y: center position
|
||||||
|
:param r: radius (overrides d)
|
||||||
|
:param d: diameter
|
||||||
|
:param w: width measured against flat side in mm
|
||||||
|
:param rel_w: width in percent
|
||||||
|
:param angle: orientation (rotation) of the flat sides
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
if r is None:
|
if r is None:
|
||||||
r = d / 2.0
|
r = d / 2.0
|
||||||
if w is None:
|
if w is None:
|
||||||
|
@ -1278,6 +1301,40 @@ class Boxes:
|
||||||
self.edge(2*r*math.sin(math.radians(a)))
|
self.edge(2*r*math.sin(math.radians(a)))
|
||||||
self.corner(-a)
|
self.corner(-a)
|
||||||
|
|
||||||
|
@restore
|
||||||
|
@holeCol
|
||||||
|
def mountingHole(self, x, y, d_shaft, d_head=0.0, angle=0, tabs=0):
|
||||||
|
"""
|
||||||
|
Draw a pear shaped mounting hole for sliding over a screw head. Total height = 1.5* d_shaft + d_head
|
||||||
|
|
||||||
|
:param x: position
|
||||||
|
:param y: postion
|
||||||
|
:param d_shaft: diameter of the screw shaft
|
||||||
|
:param d_head: diameter of the screw head
|
||||||
|
:param angle: rotation angle of the hole
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if d_shaft < (2 * self.burn):
|
||||||
|
return # no hole if diameter is smaller then the capabilities of the machine
|
||||||
|
|
||||||
|
if not d_head or d_head < (2 * self.burn): # if no head diameter is given
|
||||||
|
self.hole(x, y ,d=d_shaft, tabs=tabs) # only a round hole is generated
|
||||||
|
return
|
||||||
|
|
||||||
|
rs = d_shaft / 2
|
||||||
|
rh = d_head / 2
|
||||||
|
|
||||||
|
self.moveTo(x, y, angle)
|
||||||
|
self.moveTo(0, rs - self.burn, 0)
|
||||||
|
self.corner(-180, rs, tabs)
|
||||||
|
self.edge(2 * rs,tabs)
|
||||||
|
a = math.degrees(math.asin(rs / rh))
|
||||||
|
self.corner(90 - a, 0, tabs)
|
||||||
|
self.corner(-360 + 2 * a, rh, tabs)
|
||||||
|
self.corner(90 - a, 0, tabs)
|
||||||
|
self.edge(2 * rs, tabs)
|
||||||
|
|
||||||
@restore
|
@restore
|
||||||
def text(self, text, x=0, y=0, angle=0, align="", fontsize=10, color=[0.0, 0.0, 0.0], font="Arial"):
|
def text(self, text, x=0, y=0, angle=0, align="", fontsize=10, color=[0.0, 0.0, 0.0], font="Arial"):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -55,6 +55,7 @@ class BinTray(Boxes):
|
||||||
self.argparser.add_argument(
|
self.argparser.add_argument(
|
||||||
"--front", action="store", type=float, default=0.4,
|
"--front", action="store", type=float, default=0.4,
|
||||||
help="fraction of bin height covert with slope")
|
help="fraction of bin height covert with slope")
|
||||||
|
self.argparser.add_argument("--hole_dD", action="store", type=argparseSections, default="3.5:6.5", help="mounting hole diameter (shaft:head) in mm [\U0001F6C8](https://florianfesti.github.io/boxes/html/usermanual.html#mounting-holes)")
|
||||||
|
|
||||||
def xSlots(self):
|
def xSlots(self):
|
||||||
posx = -0.5 * self.thickness
|
posx = -0.5 * self.thickness
|
||||||
|
@ -74,6 +75,23 @@ class BinTray(Boxes):
|
||||||
self.fingerHolesAt(posy, posx, x)
|
self.fingerHolesAt(posy, posx, x)
|
||||||
posx += x + self.thickness
|
posx += x + self.thickness
|
||||||
|
|
||||||
|
def addMount(self):
|
||||||
|
ds = self.hole_dD[0]
|
||||||
|
|
||||||
|
if len(self.hole_dD) < 2: # if no head diameter is given
|
||||||
|
dh = 0 # only a round hole is generated
|
||||||
|
y = max (self.thickness * 1.25, self.thickness * 1.0 + ds) # and we assume that a typical screw head diameter is twice the shaft diameter
|
||||||
|
else:
|
||||||
|
dh = self.hole_dD[1] # use given head diameter
|
||||||
|
y = max (self.thickness * 1.25, self.thickness * 1.0 + dh / 2) # and offset the hole to have enough space for the head
|
||||||
|
|
||||||
|
dx = sum(self.sx) + self.thickness * (len(self.sx) - 1)
|
||||||
|
x1 = dx * 0.125
|
||||||
|
x2 = dx * 0.875
|
||||||
|
|
||||||
|
self.mountingHole(x1, y, ds, dh, -90)
|
||||||
|
self.mountingHole(x2, y, ds, dh, -90)
|
||||||
|
|
||||||
def xHoles(self):
|
def xHoles(self):
|
||||||
posx = -0.5 * self.thickness
|
posx = -0.5 * self.thickness
|
||||||
for x in self.sx[:-1]:
|
for x in self.sx[:-1]:
|
||||||
|
@ -102,6 +120,7 @@ class BinTray(Boxes):
|
||||||
|
|
||||||
x = sum(self.sx) + self.thickness * (len(self.sx) - 1)
|
x = sum(self.sx) + self.thickness * (len(self.sx) - 1)
|
||||||
y = sum(self.sy) + self.thickness * (len(self.sy) - 1)
|
y = sum(self.sy) + self.thickness * (len(self.sy) - 1)
|
||||||
|
|
||||||
h = self.h
|
h = self.h
|
||||||
hi = self.hi = h
|
hi = self.hi = h
|
||||||
t = self.thickness
|
t = self.thickness
|
||||||
|
@ -124,7 +143,7 @@ class BinTray(Boxes):
|
||||||
self.rectangularWall(y, h, "FFBF", move="up only")
|
self.rectangularWall(y, h, "FFBF", move="up only")
|
||||||
|
|
||||||
# floor
|
# floor
|
||||||
self.rectangularWall(x, y, "ffff", callback=[self.xSlots, self.ySlots],move="right", label="back")
|
self.rectangularWall(x, y, "ffff", callback=[self.xSlots, self.ySlots, self.addMount], move="right", label="back")
|
||||||
# Inner walls
|
# Inner walls
|
||||||
for i in range(len(self.sx) - 1):
|
for i in range(len(self.sx) - 1):
|
||||||
e = [edges.SlottedEdge(self, self.sy, "f"), "f", "B", "f"]
|
e = [edges.SlottedEdge(self, self.sy, "f"), "f", "B", "f"]
|
||||||
|
@ -139,6 +158,3 @@ class BinTray(Boxes):
|
||||||
for i in range(len(self.sy)):
|
for i in range(len(self.sy)):
|
||||||
e = [edges.SlottedEdge(self, self.sx, "g"), "F", "e", "F"]
|
e = [edges.SlottedEdge(self, self.sx, "g"), "F", "e", "F"]
|
||||||
self.rectangularWall(x, self.sy[i]*self.front*2**0.5, e, callback=[self.frontHoles(i)], move="up", label="retainer " + str(i+1))
|
self.rectangularWall(x, self.sy[i]*self.front*2**0.5, e, callback=[self.frontHoles(i)], move="up", label="retainer " + str(i+1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,8 @@ When turned by 90°, it can be also used to create a bottle holder."""
|
||||||
"--upright", action="store", type=boolarg, default=True,
|
"--upright", action="store", type=boolarg, default=True,
|
||||||
help="stack lights upright (or side by side)")
|
help="stack lights upright (or side by side)")
|
||||||
|
|
||||||
|
self.argparser.add_argument("--hole_dD", action="store", type=argparseSections, default="3.5:6.5", help="mounting hole diameter (shaft:head) in mm [\U0001F6C8](https://florianfesti.github.io/boxes/html/usermanual.html#mounting-holes)")
|
||||||
|
|
||||||
def backCB(self):
|
def backCB(self):
|
||||||
t = self.thickness
|
t = self.thickness
|
||||||
for i in range(1, self.n):
|
for i in range(1, self.n):
|
||||||
|
@ -114,6 +116,44 @@ When turned by 90°, it can be also used to create a bottle holder."""
|
||||||
|
|
||||||
self.move(overallwidth, overallheight, move, label=label)
|
self.move(overallwidth, overallheight, move, label=label)
|
||||||
|
|
||||||
|
def addMountH(self, width, height):
|
||||||
|
ds = self.hole_dD[0]
|
||||||
|
|
||||||
|
if len(self.hole_dD) < 2: # if no head diameter is given
|
||||||
|
dh = 0 # only a round hole is generated
|
||||||
|
y = height - max (self.thickness * 1.25, self.thickness * 1.0 + ds) # and we assume that a typical screw head diameter is twice the shaft diameter
|
||||||
|
else:
|
||||||
|
dh = self.hole_dD[1] # use given head diameter
|
||||||
|
y = height - max (self.thickness * 1.25, self.thickness * 1.0 + dh / 2) # and offset the hole to have enough space for the head
|
||||||
|
|
||||||
|
dx = width
|
||||||
|
x1 = dx * 0.125
|
||||||
|
x2 = dx * 0.875
|
||||||
|
|
||||||
|
self.mountingHole(x1, y, ds, dh, 90)
|
||||||
|
self.mountingHole(x2, y, ds, dh, 90)
|
||||||
|
|
||||||
|
def addMountV(self, width, height):
|
||||||
|
if self.hole_dD[0] < 2 * self.burn:
|
||||||
|
return # no hole if no diameter is given
|
||||||
|
|
||||||
|
ds = self.hole_dD[0]
|
||||||
|
|
||||||
|
if len(self.hole_dD) < 2: # if no head diameter is given
|
||||||
|
dh = 0 # only a round hole is generated
|
||||||
|
x = max (self.thickness * 2.75, self.thickness * 2.25 + ds) # and we assume that a typical screw head diameter is twice the shaft diameter
|
||||||
|
else:
|
||||||
|
dh = self.hole_dD[1] # use given head diameter
|
||||||
|
x = max (self.thickness * 2.75, self.thickness * 2.25 + dh / 2) # and offset the hole to have enough space for the head
|
||||||
|
|
||||||
|
dy = height
|
||||||
|
|
||||||
|
y1 = self.thickness * 0.75 + dy * 0.125
|
||||||
|
y2 = self.thickness * 0.75 + dy * 0.875
|
||||||
|
|
||||||
|
self.mountingHole(x, y1, ds, dh, 180)
|
||||||
|
self.mountingHole(x, y2, ds, dh, 180)
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
# adjust to the variables you want in the local scope
|
# adjust to the variables you want in the local scope
|
||||||
d, h, n = self.depth, self.h, self.n
|
d, h, n = self.depth, self.h, self.n
|
||||||
|
@ -126,7 +166,10 @@ When turned by 90°, it can be also used to create a bottle holder."""
|
||||||
self.addPart(ShadyEdge(self, None))
|
self.addPart(ShadyEdge(self, None))
|
||||||
|
|
||||||
# back
|
# back
|
||||||
self.rectangularWall(th, h, "FFFF", callback=[self.backCB], move="up", label = "back")
|
if self.upright:
|
||||||
|
self.rectangularWall(th, h, "FFFF", callback=[self.backCB, self.addMountV(th, h)], move="up", label="back")
|
||||||
|
else:
|
||||||
|
self.rectangularWall(th, h, "FFFF", callback=[self.backCB, self.addMountH(th, h)], move="up", label="back")
|
||||||
|
|
||||||
if self.upright:
|
if self.upright:
|
||||||
# sides
|
# sides
|
||||||
|
@ -164,6 +207,4 @@ When turned by 90°, it can be also used to create a bottle holder."""
|
||||||
|
|
||||||
# Colored windows
|
# Colored windows
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
self.parts.disc(h-2*t, move="right", label="colored window " + str(i+1))
|
self.parts.disc(h-2*t, move="right") # , label="colored windows") --> todo
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,9 @@ Most generators will add walls between the comparments, so the total size might
|
||||||
|
|
||||||
The sizes of the sections are divided by a colon (``:``) e.g. ``30:25.5:70``. Instead of repeating the same value they can be replaced by ``value*numberofsections`` e.g. ``50*3`` meaning the same as ``50:50:50``. To equally divide a length into several sections ``overallwidth/numberofsections`` can be used - e.g. ``120/4`` being the same as ``30:30:30:30``. All these formats can be freely mixed.
|
The sizes of the sections are divided by a colon (``:``) e.g. ``30:25.5:70``. Instead of repeating the same value they can be replaced by ``value*numberofsections`` e.g. ``50*3`` meaning the same as ``50:50:50``. To equally divide a length into several sections ``overallwidth/numberofsections`` can be used - e.g. ``120/4`` being the same as ``30:30:30:30``. All these formats can be freely mixed.
|
||||||
|
|
||||||
|
mounting_holes
|
||||||
|
..................
|
||||||
|
Some generators provide the option to create pear shaped mounting holes. To generate the right size holes, the shaft and the head diameter of the mounting screw must be configured. The format is "shaft:head", both diameters given in mm (e.g ``3.5:6.5``). If only the shaft diameter is given (e.g. ``3.5``), a round mounting hole is generated. Setting the mounting hole diameter parameter to ``0`` disables the creation of mounting holes.
|
||||||
|
|
||||||
outside
|
outside
|
||||||
.......
|
.......
|
||||||
|
|
Loading…
Reference in New Issue