diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .style.yapf | 3 | ||||
-rw-r--r-- | Boxer.py | 645 | ||||
-rw-r--r-- | BoxerGui.py | 128 | ||||
-rw-r--r-- | InitGui.py | 160 | ||||
-rw-r--r-- | Makefile | 25 |
6 files changed, 496 insertions, 466 deletions
@@ -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 @@ -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() @@ -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()) @@ -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 $@ |