aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.style.yapf3
-rw-r--r--Boxer.py645
-rw-r--r--BoxerGui.py128
-rw-r--r--InitGui.py160
-rw-r--r--Makefile25
6 files changed, 496 insertions, 466 deletions
diff --git a/.gitignore b/.gitignore
index 2e141c6..d53c58b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
*.tmp
tmp.*
*.tmp.*
+.formatted.*
diff --git a/.style.yapf b/.style.yapf
new file mode 100644
index 0000000..13cde69
--- /dev/null
+++ b/.style.yapf
@@ -0,0 +1,3 @@
+[style]
+based_on_style = pep8
+column_limit = 200
diff --git a/Boxer.py b/Boxer.py
index 0319e43..a15b03a 100644
--- a/Boxer.py
+++ b/Boxer.py
@@ -6,105 +6,111 @@ import Part
from enum import Enum
import math
+
# These names are silly, should be X, Y, Z instead
class MeasurementDirection(Enum):
- width = 1 # X
- height = 2 # Z
- depth = 3 # Y
+ width = 1 # X
+ height = 2 # Z
+ depth = 3 # Y
+
# X and Y rotation factors
class LineDirection(Enum):
- right = (1, 0, 0, 1)
- down = (0, -1, 1, 0)
- left = (-1, 0, 0, -1)
- up = (0, 1, -1, 0)
-
- def __init__(self, x_x, x_y, y_x, y_y):
- self.x_x = x_x
- self.x_y = x_y
- self.y_x = y_x
- self.y_y = y_y
+ right = (1, 0, 0, 1)
+ down = (0, -1, 1, 0)
+ left = (-1, 0, 0, -1)
+ up = (0, 1, -1, 0)
+
+ def __init__(self, x_x, x_y, y_x, y_y):
+ self.x_x = x_x
+ self.x_y = x_y
+ self.y_x = y_x
+ self.y_y = y_y
+
# Configuration for each line in a box side
class SideConfig(Enum):
- large = (False, True, False, True, False, True, False, True)
- medium = (True, True, False, False, True, True, False, False)
- small = (True, False, True, False, True, False, True, False)
-
- def __init__(self, rightInv, rightIncludeStart, downInv, downIncludeStart, leftInv, leftIncludeStart, upInv, upIncludeStart):
- self.rightInv = rightInv
- self.rightIncludeStart = rightIncludeStart
- self.downInv = downInv
- self.downIncludeStart = downIncludeStart
- self.leftInv = leftInv
- self.leftIncludeStart = leftIncludeStart
- self.upInv = upInv
- self.upIncludeStart = upIncludeStart
-
- def inv(self, direction):
- if direction == LineDirection.right:
- return self.rightInv
- elif direction == LineDirection.down:
- return self.downInv
- elif direction == LineDirection.left:
- return self.leftInv
- elif direction == LineDirection.up:
- return self.upInv
- else:
- raise Exception("Unknown direction: " + repr(direction))
-
- def includeStart(self, direction):
- if direction == LineDirection.right:
- return self.rightIncludeStart
- elif direction == LineDirection.down:
- return self.downIncludeStart
- elif direction == LineDirection.left:
- return self.leftIncludeStart
- elif direction == LineDirection.up:
- return self.upIncludeStart
- else:
- raise Exception("Unknown direction: " + repr(direction))
+ large = (False, True, False, True, False, True, False, True)
+ medium = (True, True, False, False, True, True, False, False)
+ small = (True, False, True, False, True, False, True, False)
+
+ def __init__(self, rightInv, rightIncludeStart, downInv, downIncludeStart, leftInv, leftIncludeStart, upInv, upIncludeStart):
+ self.rightInv = rightInv
+ self.rightIncludeStart = rightIncludeStart
+ self.downInv = downInv
+ self.downIncludeStart = downIncludeStart
+ self.leftInv = leftInv
+ self.leftIncludeStart = leftIncludeStart
+ self.upInv = upInv
+ self.upIncludeStart = upIncludeStart
+
+ def inv(self, direction):
+ if direction == LineDirection.right:
+ return self.rightInv
+ elif direction == LineDirection.down:
+ return self.downInv
+ elif direction == LineDirection.left:
+ return self.leftInv
+ elif direction == LineDirection.up:
+ return self.upInv
+ else:
+ raise Exception("Unknown direction: " + repr(direction))
+
+ def includeStart(self, direction):
+ if direction == LineDirection.right:
+ return self.rightIncludeStart
+ elif direction == LineDirection.down:
+ return self.downIncludeStart
+ elif direction == LineDirection.left:
+ return self.leftIncludeStart
+ elif direction == LineDirection.up:
+ return self.upIncludeStart
+ else:
+ raise Exception("Unknown direction: " + repr(direction))
+
class BoxSide(Enum):
- front = ('Front', MeasurementDirection.width, MeasurementDirection.height, SideConfig.large, (0, -1, 0))
- back = ('Back', MeasurementDirection.width, MeasurementDirection.height, SideConfig.large, (0, 1, 0))
- left = ('Left', MeasurementDirection.depth, MeasurementDirection.height, SideConfig.small, (-1, 0, 0))
- right = ('Right', MeasurementDirection.depth, MeasurementDirection.height, SideConfig.small, (1, 0, 0))
- top = ('Top', MeasurementDirection.width, MeasurementDirection.depth, SideConfig.medium, (0, 0, 1))
- bottom = ('Bottom', MeasurementDirection.width, MeasurementDirection.depth, SideConfig.medium, (0, 0, -1))
-
- def __init__(self, title, directionX, directionY, sideConfig, extrudeVector):
- self.title = title
- self.directionX = directionX
- self.directionY = directionY
- self.sideConfig = sideConfig
- self.extrudeVector = Vector(extrudeVector)
+ front = ('Front', MeasurementDirection.width, MeasurementDirection.height, SideConfig.large, (0, -1, 0))
+ back = ('Back', MeasurementDirection.width, MeasurementDirection.height, SideConfig.large, (0, 1, 0))
+ left = ('Left', MeasurementDirection.depth, MeasurementDirection.height, SideConfig.small, (-1, 0, 0))
+ right = ('Right', MeasurementDirection.depth, MeasurementDirection.height, SideConfig.small, (1, 0, 0))
+ top = ('Top', MeasurementDirection.width, MeasurementDirection.depth, SideConfig.medium, (0, 0, 1))
+ bottom = ('Bottom', MeasurementDirection.width, MeasurementDirection.depth, SideConfig.medium, (0, 0, -1))
+
+ def __init__(self, title, directionX, directionY, sideConfig, extrudeVector):
+ self.title = title
+ self.directionX = directionX
+ self.directionY = directionY
+ self.sideConfig = sideConfig
+ self.extrudeVector = Vector(extrudeVector)
+
class NotchConfig(object):
- def __init__(self, count, size):
- self.count = count
- self.size = size
+ def __init__(self, count, size):
+ self.count = count
+ self.size = size
+
+ def __str__(self):
+ return "count = " + str(self.count) + ", size = " + str(self.size)
- def __str__(self):
- return "count = " + str(self.count) + ", size = " + str(self.size)
class BoxCfg(object):
- def __init__(self):
- self._thickness = 10
- self._notchSize = 10
- self.generateExtrudes = True
- self.generateCrossSections = False # Not very useful so off by default
- self.outerDimmensions(100, 100, 100)
- self.calculate()
-
- @property
- def thickness(self):
- return self._thickness
-
- @thickness.setter
- def thickness(self, thickness):
- self._thickness = thickness
- self.calculate()
+ def __init__(self):
+ self._thickness = 10
+ self._notchSize = 10
+ self.generateExtrudes = True
+ self.generateCrossSections = False # Not very useful so off by default
+ self.outerDimmensions(100, 100, 100)
+ self.calculate()
+
+ @property
+ def thickness(self):
+ return self._thickness
+
+ @thickness.setter
+ def thickness(self, thickness):
+ self._thickness = thickness
+ self.calculate()
# TODO: replace this with a way to set number of notches in each direction
# @property
@@ -116,270 +122,275 @@ class BoxCfg(object):
# self._notches = notches
# self.calculate()
- @property
- def notchSize(self):
- return self._notchSize
-
- @notchSize.setter
- def notchSize(self, notchSize):
- self._notchSize = notchSize
-
- def outerDimmensions(self, width, height, depth):
- self.outerWidth = width
- self.outerHeight = height
- self.outerDepth = depth
- self.calculate()
- return self
-
- def notchConfig(self, direction):
- if direction == MeasurementDirection.width:
- return self._notchConfigWidth
- elif direction == MeasurementDirection.height:
- return self._notchConfigHeight
- elif direction == MeasurementDirection.depth:
- return self._notchConfigDepth
- else:
- raise Exception("Unknown MeasurementDirection: " + str(direction))
-
- def createNotchConfig(self, sideLength):
- count = sideLength / self._notchSize
- size = float(sideLength) / float(count * 2 + 1)
- return NotchConfig(count, size)
-
- def calculate(self):
- self.innerWidth = self.outerWidth - 2 * self._thickness
- self.innerHeight = self.outerHeight - 2 * self._thickness
- self.innerDepth = self.outerDepth - 2 * self._thickness
- self._notchConfigWidth = self.createNotchConfig(self.innerWidth)
- self._notchConfigHeight = self.createNotchConfig(self.innerHeight)
- self._notchConfigDepth = self.createNotchConfig(self.innerDepth)
-
- def prt(self):
- print("Box configuration")
- print("Thickness : " + str(self._thickness))
- print("Outer w/h/d: " + str(self.outerWidth) + "/" + str(self.outerHeight) + "/" + str(self.outerDepth))
- print("Inner w/h/d: " + str(self.innerWidth) + "/" + str(self.innerHeight) + "/" + str(self.innerDepth))
- print("Notch size : " + str(self._notchSize))
- print(" Width: " + str(self.notchConfig(MeasurementDirection.width)))
- print(" Height: " + str(self.notchConfig(MeasurementDirection.height)))
- print(" Depth: " + str(self.notchConfig(MeasurementDirection.depth)))
+ @property
+ def notchSize(self):
+ return self._notchSize
+
+ @notchSize.setter
+ def notchSize(self, notchSize):
+ self._notchSize = notchSize
+
+ def outerDimmensions(self, width, height, depth):
+ self.outerWidth = width
+ self.outerHeight = height
+ self.outerDepth = depth
+ self.calculate()
+ return self
+
+ def notchConfig(self, direction):
+ if direction == MeasurementDirection.width:
+ return self._notchConfigWidth
+ elif direction == MeasurementDirection.height:
+ return self._notchConfigHeight
+ elif direction == MeasurementDirection.depth:
+ return self._notchConfigDepth
+ else:
+ raise Exception("Unknown MeasurementDirection: " + str(direction))
+
+ def createNotchConfig(self, sideLength):
+ count = sideLength / self._notchSize
+ size = float(sideLength) / float(count * 2 + 1)
+ return NotchConfig(count, size)
+
+ def calculate(self):
+ self.innerWidth = self.outerWidth - 2 * self._thickness
+ self.innerHeight = self.outerHeight - 2 * self._thickness
+ self.innerDepth = self.outerDepth - 2 * self._thickness
+ self._notchConfigWidth = self.createNotchConfig(self.innerWidth)
+ self._notchConfigHeight = self.createNotchConfig(self.innerHeight)
+ self._notchConfigDepth = self.createNotchConfig(self.innerDepth)
+
+ def prt(self):
+ print("Box configuration")
+ print("Thickness : " + str(self._thickness))
+ print("Outer w/h/d: " + str(self.outerWidth) + "/" + str(self.outerHeight) + "/" + str(self.outerDepth))
+ print("Inner w/h/d: " + str(self.innerWidth) + "/" + str(self.innerHeight) + "/" + str(self.innerDepth))
+ print("Notch size : " + str(self._notchSize))
+ print(" Width: " + str(self.notchConfig(MeasurementDirection.width)))
+ print(" Height: " + str(self.notchConfig(MeasurementDirection.height)))
+ print(" Depth: " + str(self.notchConfig(MeasurementDirection.depth)))
+
class VGen(object):
- def __init__(self, current, dir):
- self.current = current
- self.dir = dir
- self.list = []
+ def __init__(self, current, dir):
+ self.current = current
+ self.dir = dir
+ self.list = []
- def move(self, x, y, z = 0):
- pos = Vector(x, y, z)
- self.current = self.current.add(pos)
- self.list.append(self.current)
+ def move(self, x, y, z=0):
+ pos = Vector(x, y, z)
+ self.current = self.current.add(pos)
+ self.list.append(self.current)
- def moveX(self, value):
- self.move(self.dir.x_x * value, self.dir.x_y * value, 0)
+ def moveX(self, value):
+ self.move(self.dir.x_x * value, self.dir.x_y * value, 0)
+
+ def moveY(self, value):
+ self.move(self.dir.y_x * value, self.dir.y_y * value, 0)
- def moveY(self, value):
- self.move(self.dir.y_x * value, self.dir.y_y * value, 0)
def line(cfg, start, lineDirection, sideConfig, notchConfig):
- inv = -1 if sideConfig.inv(lineDirection) else 1
- includeStart = sideConfig.includeStart(lineDirection)
+ inv = -1 if sideConfig.inv(lineDirection) else 1
+ includeStart = sideConfig.includeStart(lineDirection)
+
+ g = VGen(start, lineDirection)
- g = VGen(start, lineDirection)
+ if includeStart:
+ g.moveX(cfg.thickness)
- if includeStart:
- g.moveX(cfg.thickness)
+ g.moveX(notchConfig.size)
+ for i in range(0, notchConfig.count):
+ g.moveY(-cfg.thickness * inv)
+ g.moveX(notchConfig.size)
+ g.moveY(cfg.thickness * inv)
+ g.moveX(notchConfig.size)
- g.moveX(notchConfig.size)
- for i in range(0, notchConfig.count):
- g.moveY(-cfg.thickness * inv)
- g.moveX(notchConfig.size)
- g.moveY(cfg.thickness * inv)
- g.moveX(notchConfig.size)
+ if includeStart:
+ g.moveX(cfg.thickness)
- if includeStart:
- g.moveX(cfg.thickness)
+ return g.list
- return g.list
def makeBoxSide(cfg, boxSide):
- notchConfigX = cfg.notchConfig(boxSide.directionX)
- notchConfigY = cfg.notchConfig(boxSide.directionY)
-
- # Offset the start so that the inner area starts at (0, 0)
- if boxSide.sideConfig is SideConfig.large:
- start = Vector(-cfg.thickness, cfg.thickness, 0)
- elif boxSide.sideConfig is SideConfig.medium:
- start = Vector(-cfg.thickness, 0, 0)
- else:
- start = Vector(0, 0, 0)
-
- v = [start]
- top = line(cfg, v[-1], LineDirection.right, boxSide.sideConfig, notchConfigX);
- v.extend(top)
- left = line(cfg, v[-1], LineDirection.down, boxSide.sideConfig, notchConfigY);
- v.extend(left)
- bottom = line(cfg, v[-1], LineDirection.left, boxSide.sideConfig, notchConfigX);
- v.extend(bottom)
- right = line(cfg, v[-1], LineDirection.up, boxSide.sideConfig, notchConfigY);
- v.extend(right)
- return v
+ notchConfigX = cfg.notchConfig(boxSide.directionX)
+ notchConfigY = cfg.notchConfig(boxSide.directionY)
+
+ # Offset the start so that the inner area starts at (0, 0)
+ if boxSide.sideConfig is SideConfig.large:
+ start = Vector(-cfg.thickness, cfg.thickness, 0)
+ elif boxSide.sideConfig is SideConfig.medium:
+ start = Vector(-cfg.thickness, 0, 0)
+ else:
+ start = Vector(0, 0, 0)
+
+ v = [start]
+ top = line(cfg, v[-1], LineDirection.right, boxSide.sideConfig, notchConfigX)
+ v.extend(top)
+ left = line(cfg, v[-1], LineDirection.down, boxSide.sideConfig, notchConfigY)
+ v.extend(left)
+ bottom = line(cfg, v[-1], LineDirection.left, boxSide.sideConfig, notchConfigX)
+ v.extend(bottom)
+ right = line(cfg, v[-1], LineDirection.up, boxSide.sideConfig, notchConfigY)
+ v.extend(right)
+ return v
+
def makeBox(doc, cfg):
- objects = {}
-
- sep = cfg.outerWidth * 0.05
-
- def m(rotX, rotY, moveX, moveY, moveZ):
- if rotX and rotY:
- p = Placement(Vector(0, 0, 0), Rotation(Vector(1, 1, 1), 120))
- m = p.toMatrix()
- else:
- m = Matrix()
- if rotX:
- m.rotateX(math.radians(90))
- if rotY:
- m.rotateY(math.radians(90))
-
- v = Vector(cfg.innerWidth, cfg.innerDepth, cfg.innerHeight)
- v.scale(moveX, moveY, moveZ)
-
- m.move(v)
- return m
-
- # front back left
- # right top bottom
-
- s = Part.makePolygon(makeBoxSide(cfg, BoxSide.front))
- s.transformShape(m(True, False, -0.5, -0.5, 0.5))
- front = doc.addObject("Part::Feature", "Front")
- front.Shape = s
-
- s = Part.makePolygon(makeBoxSide(cfg, BoxSide.back))
- s.transformShape(m(True, False, -0.5, 0.5, 0.5))
- back = doc.addObject("Part::Feature", "Back")
- back.Shape = s
-
- l = Part.makePolygon(makeBoxSide(cfg, BoxSide.left))
- l.transformShape(m(True, True, -0.5, -0.5, 0.5))
- left = doc.addObject("Part::Feature", "Left")
- left.Shape = l
-
- l = Part.makePolygon(makeBoxSide(cfg, BoxSide.right))
- l.transformShape(m(True, True, 0.5, -0.5, 0.5))
- right = doc.addObject("Part::Feature", "Right")
- right.Shape = l
-
- l = Part.makePolygon(makeBoxSide(cfg, BoxSide.top))
- l.transformShape(m(False, False, -0.5, 0.5, 0.5))
- top = doc.addObject("Part::Feature", "Top")
- top.Shape = l
-
- l = Part.makePolygon(makeBoxSide(cfg, BoxSide.bottom))
- l.transformShape(m(False, False, -0.5, 0.5, -0.5))
- bottom = doc.addObject("Part::Feature", "Bottom")
- bottom.Shape = l
-
- #front.ViewObject.Visibility = False
- #back.ViewObject.Visibility = False
- #left.ViewObject.Visibility = False
- #right.ViewObject.Visibility = False
- #top.ViewObject.Visibility = False
- #bottom.ViewObject.Visibility = False
-
- return {'front': front, 'back': back,
- 'left': left, 'right': right,
- 'top': top, 'bottom': bottom}
+ objects = {}
+
+ sep = cfg.outerWidth * 0.05
+
+ def m(rotX, rotY, moveX, moveY, moveZ):
+ if rotX and rotY:
+ p = Placement(Vector(0, 0, 0), Rotation(Vector(1, 1, 1), 120))
+ m = p.toMatrix()
+ else:
+ m = Matrix()
+ if rotX:
+ m.rotateX(math.radians(90))
+ if rotY:
+ m.rotateY(math.radians(90))
+
+ v = Vector(cfg.innerWidth, cfg.innerDepth, cfg.innerHeight)
+ v.scale(moveX, moveY, moveZ)
+
+ m.move(v)
+ return m
+
+ # front back left
+ # right top bottom
+
+ s = Part.makePolygon(makeBoxSide(cfg, BoxSide.front))
+ s.transformShape(m(True, False, -0.5, -0.5, 0.5))
+ front = doc.addObject("Part::Feature", "Front")
+ front.Shape = s
+
+ s = Part.makePolygon(makeBoxSide(cfg, BoxSide.back))
+ s.transformShape(m(True, False, -0.5, 0.5, 0.5))
+ back = doc.addObject("Part::Feature", "Back")
+ back.Shape = s
+
+ l = Part.makePolygon(makeBoxSide(cfg, BoxSide.left))
+ l.transformShape(m(True, True, -0.5, -0.5, 0.5))
+ left = doc.addObject("Part::Feature", "Left")
+ left.Shape = l
+
+ l = Part.makePolygon(makeBoxSide(cfg, BoxSide.right))
+ l.transformShape(m(True, True, 0.5, -0.5, 0.5))
+ right = doc.addObject("Part::Feature", "Right")
+ right.Shape = l
+
+ l = Part.makePolygon(makeBoxSide(cfg, BoxSide.top))
+ l.transformShape(m(False, False, -0.5, 0.5, 0.5))
+ top = doc.addObject("Part::Feature", "Top")
+ top.Shape = l
+
+ l = Part.makePolygon(makeBoxSide(cfg, BoxSide.bottom))
+ l.transformShape(m(False, False, -0.5, 0.5, -0.5))
+ bottom = doc.addObject("Part::Feature", "Bottom")
+ bottom.Shape = l
+
+ #front.ViewObject.Visibility = False
+ #back.ViewObject.Visibility = False
+ #left.ViewObject.Visibility = False
+ #right.ViewObject.Visibility = False
+ #top.ViewObject.Visibility = False
+ #bottom.ViewObject.Visibility = False
+
+ return {'front': front, 'back': back, 'left': left, 'right': right, 'top': top, 'bottom': bottom}
+
def makeExtrudes(doc, cfg):
-
- def makeExtrude(doc, cfg, side, part):
- extrude = doc.addObject("Part::Extrusion", side.title + "_Extrude")
- extrude.Base = part
- extrude.Dir = side.extrudeVector * cfg.thickness
- extrude.Solid = (True)
- extrude.TaperAngle = (0)
- extrude.Label = side.title + ' Extrude'
-
- partView = part.ViewObject
- extrudeView = extrude.ViewObject
-
- if partView is not None and extrudeView is not None:
- partView.Visibility = False
- extrudeView.ShapeColor = partView.ShapeColor
- extrudeView.LineColor = partView.LineColor
- extrudeView.PointColor = partView.PointColor
-
- return extrude
-
- objects = {}
- objects['front'] = makeExtrude(doc, cfg, BoxSide.front, doc.Front)
- objects['back'] = makeExtrude(doc, cfg, BoxSide.back, doc.Back)
- objects['left'] = makeExtrude(doc, cfg, BoxSide.left, doc.Left)
- objects['right'] = makeExtrude(doc, cfg, BoxSide.right, doc.Right)
- objects['top'] = makeExtrude(doc, cfg, BoxSide.top, doc.Top)
- objects['bottom'] = makeExtrude(doc, cfg, BoxSide.bottom, doc.Bottom)
-
- #objects['front'].ViewObject.Visibility = False
- #objects['back'].ViewObject.Visibility = False
- #objects['left'].ViewObject.Visibility = False
- #objects['right'].ViewObject.Visibility = False
- #objects['top'].ViewObject.Visibility = False
- #objects['bottom'].ViewObject.Visibility = False
-
- return objects
+ def makeExtrude(doc, cfg, side, part):
+ extrude = doc.addObject("Part::Extrusion", side.title + "_Extrude")
+ extrude.Base = part
+ extrude.Dir = side.extrudeVector * cfg.thickness
+ extrude.Solid = (True)
+ extrude.TaperAngle = (0)
+ extrude.Label = side.title + ' Extrude'
+
+ partView = part.ViewObject
+ extrudeView = extrude.ViewObject
+
+ if partView is not None and extrudeView is not None:
+ partView.Visibility = False
+ extrudeView.ShapeColor = partView.ShapeColor
+ extrudeView.LineColor = partView.LineColor
+ extrudeView.PointColor = partView.PointColor
+
+ return extrude
+
+ objects = {}
+ objects['front'] = makeExtrude(doc, cfg, BoxSide.front, doc.Front)
+ objects['back'] = makeExtrude(doc, cfg, BoxSide.back, doc.Back)
+ objects['left'] = makeExtrude(doc, cfg, BoxSide.left, doc.Left)
+ objects['right'] = makeExtrude(doc, cfg, BoxSide.right, doc.Right)
+ objects['top'] = makeExtrude(doc, cfg, BoxSide.top, doc.Top)
+ objects['bottom'] = makeExtrude(doc, cfg, BoxSide.bottom, doc.Bottom)
+
+ #objects['front'].ViewObject.Visibility = False
+ #objects['back'].ViewObject.Visibility = False
+ #objects['left'].ViewObject.Visibility = False
+ #objects['right'].ViewObject.Visibility = False
+ #objects['top'].ViewObject.Visibility = False
+ #objects['bottom'].ViewObject.Visibility = False
+
+ return objects
+
def makeCrossSections(doc, cfg, extrudes):
- def makeCrossSection(extrude, name):
- wires = list()
- shape = extrude.Shape
+ def makeCrossSection(extrude, name):
+ wires = list()
+ shape = extrude.Shape
+
+ for i in shape.slice(Base.Vector(0, 0, 1), cfg.thickness / 2):
+ wires.append(i)
- for i in shape.slice(Base.Vector(0, 0, 1), cfg.thickness / 2):
- wires.append(i)
+ comp = Part.Compound(wires)
+ cs = doc.addObject("Part::Feature", name + "_Cross_Section")
+ cs.Shape = comp
+ cs.ViewObject.Visibility = False
+ cs.purgeTouched()
+ return cs
- comp = Part.Compound(wires)
- cs = doc.addObject("Part::Feature", name + "_Cross_Section")
- cs.Shape = comp
- cs.ViewObject.Visibility = False
- cs.purgeTouched()
- return cs
+ objects = {}
+ for key, extrude in extrudes.items():
+ objects[key] = makeCrossSection(extrude, key.title())
+ return objects
- objects = {}
- for key, extrude in extrudes.items():
- objects[key] = makeCrossSection(extrude, key.title())
- return objects
def make(doc, cfg):
- # Cretate the underlying parts
- parts = makeBox(doc, cfg)
+ # Cretate the underlying parts
+ parts = makeBox(doc, cfg)
+
+ if cfg.generateExtrudes:
+ extrudes = makeExtrudes(doc, cfg)
+
+ box = doc.addObject("App::DocumentObjectGroup", "Box")
+ for e in extrudes.values():
+ box.addObject(e)
- if cfg.generateExtrudes:
- extrudes = makeExtrudes(doc, cfg)
-
- box = doc.addObject("App::DocumentObjectGroup", "Box")
- for e in extrudes.values():
- box.addObject(e)
+ doc.recompute()
- doc.recompute()
+ crossSections = None
+ if cfg.generateCrossSections:
+ crossSections = makeCrossSections(doc, cfg, extrudes)
+ crossSectionsGroup = doc.addObject("App::DocumentObjectGroup", "Cross Sections")
+ [crossSectionsGroup.addObject(cs) for cs in crossSections.values()]
- crossSections = None
- if cfg.generateCrossSections:
- crossSections = makeCrossSections(doc, cfg, extrudes)
- crossSectionsGroup = doc.addObject("App::DocumentObjectGroup", "Cross Sections")
- [crossSectionsGroup.addObject(cs) for cs in crossSections.values()]
+ return {'parts': parts, 'extrudes': extrudes, 'crossSections': crossSections}
- return {'parts': parts, 'extrudes': extrudes, 'crossSections': crossSections};
def removeEverything(doc):
- def rm(name):
- if hasattr(doc, name):
- doc.removeObject(name)
+ def rm(name):
+ if hasattr(doc, name):
+ doc.removeObject(name)
- rm("Box")
- rm("Cross Sections")
+ rm("Box")
+ rm("Cross Sections")
- for key in ['Front', 'Back', 'Left', 'Right', 'Top', 'Bottom']:
- rm(key + '_Cross_Section')
- rm(key + '_Extrude')
- rm(key)
+ for key in ['Front', 'Back', 'Left', 'Right', 'Top', 'Bottom']:
+ rm(key + '_Cross_Section')
+ rm(key + '_Extrude')
+ rm(key)
diff --git a/BoxerGui.py b/BoxerGui.py
index 5cb8315..2242e4a 100644
--- a/BoxerGui.py
+++ b/BoxerGui.py
@@ -3,23 +3,24 @@ from FreeCAD import Gui
from PySide import QtGui, QtCore
import Boxer, BoxerDockWidget
+
class BoxerDocumentObserver:
- def __init__(self):
- pass
+ def __init__(self):
+ pass
# def slotCreatedDocument(self, doc):
# print('slotCreatedDocument')
- def slotDeletedDocument(self, doc):
- print('slotDeletedDocument')
- gui.dockWidget.ui.generateButton.setEnabled(False)
+ def slotDeletedDocument(self, doc):
+ print('slotDeletedDocument')
+ gui.dockWidget.ui.generateButton.setEnabled(False)
# def slotRelabelDocument(self, doc):
# print('slotRelabelDocument')
- def slotActivateDocument(self, doc):
- print('slotActivateDocument')
- gui.dockWidget.ui.generateButton.setEnabled(True)
+ def slotActivateDocument(self, doc):
+ print('slotActivateDocument')
+ gui.dockWidget.ui.generateButton.setEnabled(True)
# def slotCreatedObject(self, obj):
# print('slotCreatedObject')
@@ -30,65 +31,62 @@ class BoxerDocumentObserver:
# def slotChangedObject(self, obj, prop):
# print('slotChangedObject')
+
class BoxerGui(object):
+ def __init__(self):
+ self.cfg = Boxer.BoxCfg().outerDimmensions(100, 100, 100)
+ self.cfg.notchUnitWidth = 10
+ self.cfg.thickness = 10
+
+ def setupGui(self):
+ doc = FreeCAD.ActiveDocument
+
+ self.dockWidget = dockWidget = QtGui.QDockWidget()
+ dockWidget.setWindowTitle("Box config")
+ dockWidget.ui = BoxerDockWidget.Ui_BoxerDockWidget()
+ dockWidget.generateClicked = self.generateButtonClicked
+ dockWidget.fitAllClicked = self.fitAllButtonClicked
+ dockWidget.ui.setupUi(dockWidget)
+ dockWidget.ui.generateButton.setEnabled(doc is not None)
+ dockWidget.ui.outerWidth.setValue(self.cfg.outerWidth)
+ dockWidget.ui.outerHeight.setValue(self.cfg.outerHeight)
+ dockWidget.ui.outerDepth.setValue(self.cfg.outerDepth)
+ dockWidget.ui.thickness.setValue(self.cfg.thickness)
+ dockWidget.ui.notchSize.setValue(self.cfg.notchUnitWidth)
+
+ self.documentObserver = BoxerDocumentObserver()
+ FreeCAD.addDocumentObserver(self.documentObserver)
+
+ def generateButtonClicked(self):
+ ui = self.dockWidget.ui
+
+ self.cfg.outerDimmensions(ui.outerWidth.value(), ui.outerHeight.value(), ui.outerDepth.value())
+ self.cfg.thickness = self.dockWidget.ui.thickness.value()
+ self.cfg.notchSize = self.dockWidget.ui.notchSize.value()
+
+ self.cfg.prt()
+ doc = FreeCAD.ActiveDocument
+ Boxer.removeEverything(doc)
+ objects = Boxer.make(doc, self.cfg)
+
+ itemsToSelect = objects['parts']
+
+ extrudes = objects['extrudes']
+ if extrudes is not None:
+ itemsToSelect = extrudes
+
+ Gui.Selection.clearSelection()
+ [Gui.Selection.addSelection(e) for e in itemsToSelect.values()]
+ Gui.SendMsgToActiveView("ViewSelection")
+ Gui.Selection.clearSelection()
+
+ def removeBox(self):
+ doc = FreeCAD.ActiveDocument
+ Boxer.removeEverything(doc)
+
+ def fitAllButtonClicked(self):
+ Gui.SendMsgToActiveView("ViewFit")
- def __init__(self):
- self.cfg = Boxer.BoxCfg().outerDimmensions(100, 100, 100)
- self.cfg.notchUnitWidth = 10
- self.cfg.thickness = 10
-
- def setupGui(self):
- doc = FreeCAD.ActiveDocument
-
- self.dockWidget = dockWidget = QtGui.QDockWidget()
- dockWidget.setWindowTitle("Box config")
- dockWidget.ui = BoxerDockWidget.Ui_BoxerDockWidget()
- dockWidget.generateClicked = self.generateButtonClicked
- dockWidget.fitAllClicked = self.fitAllButtonClicked
- dockWidget.ui.setupUi(dockWidget)
- dockWidget.ui.generateButton.setEnabled(doc is not None)
- dockWidget.ui.outerWidth.setValue(self.cfg.outerWidth)
- dockWidget.ui.outerHeight.setValue(self.cfg.outerHeight)
- dockWidget.ui.outerDepth.setValue(self.cfg.outerDepth)
- dockWidget.ui.thickness.setValue(self.cfg.thickness)
- dockWidget.ui.notchSize.setValue(self.cfg.notchUnitWidth)
-
- self.documentObserver = BoxerDocumentObserver()
- FreeCAD.addDocumentObserver(self.documentObserver)
-
- def generateButtonClicked(self):
- ui = self.dockWidget.ui
-
- self.cfg.outerDimmensions(
- ui.outerWidth.value(),
- ui.outerHeight.value(),
- ui.outerDepth.value())
- self.cfg.thickness = self.dockWidget.ui.thickness.value()
- self.cfg.notchSize = self.dockWidget.ui.notchSize.value()
-
- self.cfg.prt()
- doc = FreeCAD.ActiveDocument
- Boxer.removeEverything(doc)
- objects = Boxer.make(doc, self.cfg)
-
- itemsToSelect = objects['parts']
-
- extrudes = objects['extrudes']
- if extrudes is not None:
- itemsToSelect = extrudes
-
- Gui.Selection.clearSelection()
- [Gui.Selection.addSelection(e) for e in itemsToSelect.values()]
- Gui.SendMsgToActiveView("ViewSelection")
- Gui.Selection.clearSelection()
-
-
- def removeBox(self):
- doc = FreeCAD.ActiveDocument
- Boxer.removeEverything(doc)
-
- def fitAllButtonClicked(self):
- Gui.SendMsgToActiveView("ViewFit")
gui = BoxerGui()
gui.setupGui()
diff --git a/InitGui.py b/InitGui.py
index fe85dd3..c210802 100644
--- a/InitGui.py
+++ b/InitGui.py
@@ -1,105 +1,107 @@
class MakeBoxCommandClass():
- def GetResources(self):
- return {#'Pixmap' : os.path.join( iconPath , 'AddWall.svg') , # the name of a svg file available in the resources
- 'MenuText': "Make Box" ,
- 'ToolTip' : "Extends a wall from a side face of metal sheet"}
-
- def Activated(self):
- from Boxer import BoxCfg, makeBox
- # TODO: put all objects in a group:
- # group = doc.addObject("App::DocumentObjectGroup","Group")
+ def GetResources(self):
+ return { #'Pixmap' : os.path.join( iconPath , 'AddWall.svg') , # the name of a svg file available in the resources
+ 'MenuText': "Make Box",
+ 'ToolTip': "Extends a wall from a side face of metal sheet"
+ }
- cfg = BoxCfg().outerDimmensions(300, 100, 50)
- # cfg.notches = 2
- cfg.notchUnitWidth = 10
- cfg.thickness = 10
- cfg.prt()
+ def Activated(self):
+ from Boxer import BoxCfg, makeBox
+ # TODO: put all objects in a group:
+ # group = doc.addObject("App::DocumentObjectGroup","Group")
+
+ cfg = BoxCfg().outerDimmensions(300, 100, 50)
+ # cfg.notches = 2
+ cfg.notchUnitWidth = 10
+ cfg.thickness = 10
+ cfg.prt()
+
+ doc = FreeCAD.ActiveDocument
+ makeBox(doc, cfg)
- doc = FreeCAD.ActiveDocument
- makeBox(doc, cfg)
+ doc.recompute()
+ Gui.SendMsgToActiveView("ViewFit")
- doc.recompute()
- Gui.SendMsgToActiveView("ViewFit")
+ return
- return
+ def IsActive(self):
+ return FreeCAD.ActiveDocument is not None
- def IsActive(self):
- return FreeCAD.ActiveDocument is not None
class RemoveBoxCommandClass():
- def GetResources(self):
- return {
- 'MenuText': "Remove Box",
- 'ToolTip' : "Remove the box"}
-
- def Activated(self):
- import BoxerGui
- BoxerGui.gui.removeBox()
-
- def IsActive(self):
- return FreeCAD.ActiveDocument is not None
+ def GetResources(self):
+ return {'MenuText': "Remove Box", 'ToolTip': "Remove the box"}
+
+ def Activated(self):
+ import BoxerGui
+ BoxerGui.gui.removeBox()
+
+ def IsActive(self):
+ return FreeCAD.ActiveDocument is not None
+
class ShowPanelCommandClass():
- def GetResources(self):
- return {
- 'MenuText': "Show Panel"}
-
- def Activated(self):
- from PySide import QtCore
- import BoxerGui
- print('ShowPanelCommandClass.Activated')
-
- #dockWidget = QtGui.QDockWidget()
- #dockWidget.setWindowTitle("Boxer 3")
- #dockWidget.resize(656, 300)
- #dockWidget.setObjectName("BoxerDockWidget")
- #verticalLayout = QtGui.QVBoxLayout(dockWidget)
- #verticalLayout.setObjectName("verticalLayout")
- #tabSizeLabel = QtGui.QLabel(dockWidget)
- #tabSizeLabel.setObjectName("tabSizeLabel")
- #tabSizeLabel.setText("Tab size")
-
- window = FreeCADGui.getMainWindow()
- window.addDockWidget(QtCore.Qt.RightDockWidgetArea, BoxerGui.gui.dockWidget)
- BoxerGui.gui.dockWidget.show()
-
-# app = QtGui.qApp
-# window = app.activeWindow()
-# window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dockWidget)
-
-# d = QtGui.QWidget()
-# d.ui = BoxerDockWidget.Ui_BoxerDockWidget()
-# d.ui.setupUi(d)
-# d.show()
-
- return
-
- def IsActive(self):
- return True
+ def GetResources(self):
+ return {'MenuText': "Show Panel"}
+
+ def Activated(self):
+ from PySide import QtCore
+ import BoxerGui
+ print('ShowPanelCommandClass.Activated')
+
+ #dockWidget = QtGui.QDockWidget()
+ #dockWidget.setWindowTitle("Boxer 3")
+ #dockWidget.resize(656, 300)
+ #dockWidget.setObjectName("BoxerDockWidget")
+ #verticalLayout = QtGui.QVBoxLayout(dockWidget)
+ #verticalLayout.setObjectName("verticalLayout")
+ #tabSizeLabel = QtGui.QLabel(dockWidget)
+ #tabSizeLabel.setObjectName("tabSizeLabel")
+ #tabSizeLabel.setText("Tab size")
+
+ window = FreeCADGui.getMainWindow()
+ window.addDockWidget(QtCore.Qt.RightDockWidgetArea, BoxerGui.gui.dockWidget)
+ BoxerGui.gui.dockWidget.show()
+
+ # app = QtGui.qApp
+ # window = app.activeWindow()
+ # window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dockWidget)
+
+ # d = QtGui.QWidget()
+ # d.ui = BoxerDockWidget.Ui_BoxerDockWidget()
+ # d.ui.setupUi(d)
+ # d.show()
+
+ return
+
+ def IsActive(self):
+ return True
+
class BoxerWorkbench(Workbench):
-
+
MenuText = "Boxer"
ToolTip = "Box Maker"
-
+
def Initialize(self):
- self.list = ["BoxerMakeBox", "BoxerRemoveBox", "BoxerShowPanel"]
- self.appendToolbar("Boxer Commands", self.list)
- import BoxerGui # Loads the Boxer modules
+ self.list = ["BoxerMakeBox", "BoxerRemoveBox", "BoxerShowPanel"]
+ self.appendToolbar("Boxer Commands", self.list)
+ import BoxerGui # Loads the Boxer modules
def Activated(self):
- Gui.runCommand('BoxerShowPanel')
- return
-
+ Gui.runCommand('BoxerShowPanel')
+ return
+
def Deactivated(self):
return
-
+
def ContextMenu(self, recipient):
self.appendContextMenu("Boxer", self.list)
-
- def GetClassName(self):
+
+ def GetClassName(self):
return "Gui::PythonWorkbench"
+
Gui.addCommand('BoxerMakeBox', MakeBoxCommandClass())
Gui.addCommand('BoxerRemoveBox', RemoveBoxCommandClass())
Gui.addCommand('BoxerShowPanel', ShowPanelCommandClass())
diff --git a/Makefile b/Makefile
index d88fa9c..d547c60 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,26 @@
-PY=BoxerPanelWidget.py BoxerDockWidget.py
+UI=BoxerDockWidget.ui
+GEN_PY=$(patsubst %.ui,%.py,$(UI))
+SRC_PY=$(filter-out $(GEN_PY), $(wildcard *.py))
+FORMATTED_COOKIE=$(patsubst %,.formatted.%,$(SRC_PY))
-all: $(PY)
+all: $(GEN_PY)
-clean:
- rm -f $(PY)
+reformat: clean-formatted-cookie format
-#BoxerPanelWidget.py: BoxerPanelWidget.ui
+format: $(FORMATTED_COOKIE)
+
+clean: clean-gen clean-formatted-cookie
+
+clean-formatted-cookie:
+ rm -f $(FORMATTED_COOKIE)
+
+clean-gen:
+ rm -f $(GEN_PY)
%.py: %.ui
pyside-uic -o $@ $<
+
+.formatted.%.py: %.py .style.yapf
+ @echo yapf -i $(filter %.py,$<)
+ @yapf -i $(filter %.py,$<); if [ "$$?" = 2 ]; then exit 0; fi
+ @touch $@