diff options
-rw-r--r-- | Boxer.py | 230 |
1 files changed, 153 insertions, 77 deletions
@@ -1,11 +1,94 @@ +# import Boxer; reload(Boxer); Gui.runCommand("BoxerRemoveBox"); Gui.runCommand("BoxerMakeBox"); + import FreeCAD from FreeCAD import Base, Vector, Matrix import Part +from enum import Enum + +class MeasurementDirection(Enum): + width = 1 + height = 2 + depth = 3 + +# 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 + +# Configuration for each line in a box side +class SideConfig(Enum): + large = (False, True, False, True, False, True, False, True) + medium = (False, False, True, True, False, False, True, True) + 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 = (MeasurementDirection.width, MeasurementDirection.height, SideConfig.large) + back = (MeasurementDirection.width, MeasurementDirection.height, SideConfig.large) + left = (MeasurementDirection.depth, MeasurementDirection.height, SideConfig.medium) + right = (MeasurementDirection.depth, MeasurementDirection.height, SideConfig.small) + top = (MeasurementDirection.width, MeasurementDirection.depth, SideConfig.small) + bottom = (MeasurementDirection.width, MeasurementDirection.depth, SideConfig.medium) + + def __init__(self, directionX, directionY, sideConfig): + self.directionX = directionX + self.directionY = directionY + self.sideConfig = sideConfig + +class NotchConfig(object): + def __init__(self, count, size): + self.count = count + self.size = size + + def __str__(self): + return "count = " + str(self.count) + ", size = " + str(self.size) class BoxCfg(object): def __init__(self): self._thickness = 10 - self._notches = 10 +# self._notches = 10 + self._notchSize = 10 self.outerDimmensions(100, 100, 100) self.calculate() @@ -18,14 +101,23 @@ class BoxCfg(object): self._thickness = thickness self.calculate() +# TODO: replace this with a way to set number of notches in each direction +# @property +# def notches(self): +# return self._notches +# +# @notches.setter +# def notches(self, notches): +# self._notches = notches +# self.calculate() + @property - def notches(self): - return self._notches + def notchSize(self): + return self._notchUnitWidth - @notches.setter - def notches(self, notches): - self._notches = notches - self.calculate() + @notchSize.setter + def notchSize(self, notchSize): + self._notchSize = notchSize def outerDimmensions(self, width, height, depth): self.outerWidth = width @@ -34,46 +126,41 @@ class BoxCfg(object): self.calculate() return self - @property - def notchDownWidth(self): - return self._notchDownWidth + 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 = sideLength / (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._notchDownWidth = self.innerWidth / (self._notches * 2 + 1) + 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("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 count: " + str(self.notches) + ", low notch width: " + str(self.notchDownWidth)) + 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): - 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.dir = dir self.current = current self.list = [] @@ -83,58 +170,46 @@ class VGen(object): self.list.append(self.current) def moveX(self, value): - self.move(self.x_x * value, self.x_y * value, 0) + self.move(self.dir.x_x * value, self.dir.x_y * value, 0) def moveY(self, value): - self.move(self.y_x * value, self.y_y * value, 0) + self.move(self.dir.y_x * value, self.dir.y_y * value, 0) -def line1(cfg, start, dir, inv, include_start): - x = cfg.notchDownWidth +def line(cfg, start, lineDirection, sideConfig, notchConfig): - if inv: - inv = -1 - else: - inv = 1 + inv = -1 if sideConfig.inv(lineDirection) else 1 + includeStart = sideConfig.includeStart(lineDirection) - g = VGen(start, dir) + g = VGen(start, lineDirection) - if include_start: + if includeStart: g.moveX(cfg.thickness) - g.moveX(x) - for i in range(0, cfg.notches): + g.moveX(notchConfig.size) + for i in range(0, notchConfig.count): g.moveY(-cfg.thickness * inv) - g.moveX(x) + g.moveX(notchConfig.size) g.moveY(cfg.thickness * inv) - g.moveX(x) + g.moveX(notchConfig.size) - if include_start: + if includeStart: 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 makeBoxSide(cfg, boxSide): + notchConfigX = cfg.notchConfig(boxSide.directionX) + notchConfigY = cfg.notchConfig(boxSide.directionY) -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) + v = [Vector(0, 0, 0)] + 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): @@ -145,37 +220,37 @@ def makeBox(doc, cfg): m = Matrix() m.move(cfg.outerWidth * -0.55, 0, 0) - s = Part.makePolygon(largePolygon(cfg)) + s = Part.makePolygon(makeBoxSide(cfg, BoxSide.front)) s.transformShape(m) doc.addObject("Part::Feature", "Front").Shape = s m = Matrix() m.move(cfg.outerWidth * 0.55, 0, 0) - s = Part.makePolygon(largePolygon(cfg)) + s = Part.makePolygon(makeBoxSide(cfg, BoxSide.back)) s.transformShape(m) doc.addObject("Part::Feature", "Back").Shape = s m = Matrix() m.move(cfg.outerWidth * 1.60, 0, 0) - l = Part.makePolygon(mediumPolygon(cfg)) + l = Part.makePolygon(makeBoxSide(cfg, BoxSide.left)) l.transformShape(m) doc.addObject("Part::Feature", "Left").Shape = l m = Matrix() m.move(cfg.outerWidth * -0.55, cfg.outerWidth * -1.1, 0) - l = Part.makePolygon(smallPolygon(cfg)) + l = Part.makePolygon(makeBoxSide(cfg, BoxSide.right)) l.transformShape(m) doc.addObject("Part::Feature", "Right").Shape = l m = Matrix() m.move(cfg.outerWidth * 0.55, cfg.outerWidth * -1.1, 0) - l = Part.makePolygon(smallPolygon(cfg)) + l = Part.makePolygon(makeBoxSide(cfg, BoxSide.top)) l.transformShape(m) doc.addObject("Part::Feature", "Top").Shape = l m = Matrix() m.move(cfg.outerWidth * 1.60, cfg.outerWidth * -1.1, 0) - l = Part.makePolygon(mediumPolygon(cfg)) + l = Part.makePolygon(makeBoxSide(cfg, BoxSide.bottom)) l.transformShape(m) doc.addObject("Part::Feature", "Bottom").Shape = l @@ -190,7 +265,8 @@ class MakeBoxCommandClass(): # group = doc.addObject("App::DocumentObjectGroup","Group") cfg = BoxCfg().outerDimmensions(300, 100, 50) - cfg.notches = 2 + # cfg.notches = 2 + cfg.notchUnitWidth = 10 cfg.thickness = 10 cfg.prt() |