def test45(self): '''Check offsetting a single inside edge not forward.''' obj = doc.getObjectsByLabel('offset-edge')[0] w = getWireInside(obj) length = 20 * math.cos(math.pi/6) for e in w.Edges: self.assertRoughly(length, e.Length) # let's offset the horizontal edge for starters hEdges = [e for e in w.Edges if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y)] x = length / 2 y = -5 self.assertEqual(1, len(hEdges)) edge = hEdges[0] self.assertCoincide(Vector(-x, y, 0), edge.Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), edge.Vertexes[1].Point) wire = PathOpTools.offsetWire(Part.Wire([edge]), obj.Shape, 2, False) self.assertEqual(1, len(wire.Edges)) y = y + 2 self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[1].Point) # make sure we get the same result even if the edge is oriented the other way edge = PathGeom.flipEdge(edge) wire = PathOpTools.offsetWire(Part.Wire([edge]), obj.Shape, 2, False) self.assertEqual(1, len(wire.Edges)) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[1].Point)
def test38(self): '''Check offsetting a shape hole.''' obj = doc.getObjectsByLabel('shape-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(6, len(wire.Edges)) self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) length = 40 radius = 20 - 3 for e in wire.Edges: if Part.Line == type(e.Curve): self.assertRoughly(length, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(6, len(wire.Edges)) self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) for e in wire.Edges: if Part.Line == type(e.Curve): self.assertRoughly(length, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis)
def test47(self): '''Check offsetting multiple backwards inside edges.''' # This is exactly the same as test36 except that the wire is flipped to make # sure it's orientation doesn't matter obj = doc.getObjectsByLabel('offset-edge')[0] w = getWireInside(obj) length = 20 * math.cos(math.pi/6) # let's offset the other two legs lEdges = [e for e in w.Edges if not PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y)] self.assertEqual(2, len(lEdges)) w = PathGeom.flipWire(Part.Wire(lEdges)) wire = PathOpTools.offsetWire(w, obj.Shape, 2, True) x = length/2 - 2 * math.cos(math.pi/6) y = -5 - 2 * math.sin(math.pi/6) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges)) #offset the other way wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges))
def test46(self): '''Check offsetting multiple inside edges.''' obj = doc.getObjectsByLabel('offset-edge')[0] w = getWireInside(obj) length = 20 * math.cos(math.pi/6) # let's offset the other two legs lEdges = [e for e in w.Edges if not PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y)] self.assertEqual(2, len(lEdges)) wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, True) x = length/2 - 2 * math.cos(math.pi/6) y = -5 - 2 * math.sin(math.pi/6) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges)) #offset the other way wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges))
def test36(self): '''Check offsetting a square hole.''' obj = doc.getObjectsByLabel('square-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(4, len(wire.Edges)) self.assertEqual( 4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) for e in wire.Edges: if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertRoughly(34, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertRoughly(54, e.Length) self.assertFalse(PathOpTools.isWireClockwise(wire)) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(4, len(wire.Edges)) self.assertEqual( 4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) for e in wire.Edges: if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertRoughly(34, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertRoughly(54, e.Length) self.assertTrue(PathOpTools.isWireClockwise(wire))
def test46(self): '''Check offsetting multiple inside edges.''' obj = doc.getObjectsByLabel('offset-edge')[0] w = getWireInside(obj) length = 20 * math.cos(math.pi / 6) # let's offset the other two legs lEdges = [ e for e in w.Edges if not PathGeom.isRoughly( e.Vertexes[0].Point.y, e.Vertexes[1].Point.y) ] self.assertEqual(2, len(lEdges)) wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, True) x = length / 2 - 2 * math.cos(math.pi / 6) y = -5 - 2 * math.sin(math.pi / 6) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges)) #offset the other way wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges))
def test38(self): '''Check offsetting a shape hole.''' obj = doc.getObjectsByLabel('shape-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(6, len(wire.Edges)) self.assertEqual( 3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual( 3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) length = 40 radius = 20 - 3 for e in wire.Edges: if Part.Line == type(e.Curve): self.assertRoughly(length, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(6, len(wire.Edges)) self.assertEqual( 3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual( 3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) for e in wire.Edges: if Part.Line == type(e.Curve): self.assertRoughly(length, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis)
def test32(self): '''Check offsetting a box.''' obj = doc.getObjectsByLabel('square-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, True) self.assertEqual(8, len(wire.Edges)) self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual(4, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) for e in wire.Edges: if Part.Line == type(e.Curve): if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertEqual(40, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertEqual(60, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) self.assertTrue(PathOpTools.isWireClockwise(wire)) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, False) self.assertEqual(8, len(wire.Edges)) self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual(4, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) for e in wire.Edges: if Part.Line == type(e.Curve): if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertEqual(40, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertEqual(60, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) self.assertFalse(PathOpTools.isWireClockwise(wire))
def test20(self): '''Check offsetting hole wire succeeds.''' obj = doc.getObjectsByLabel('offset-edge')[0] small = getWireInside(obj) # sanity check y = 10 x = 10 * math.cos(math.pi / 6) self.assertLines(small.Edges, False, [ Vector(0, y, 0), Vector(-x, -y / 2, 0), Vector(x, -y / 2, 0), Vector(0, y, 0) ]) wire = PathOpTools.offsetWire(small, obj.Shape, 3, True) self.assertIsNotNone(wire) self.assertEqual(3, len(wire.Edges)) self.assertTrue(wire.isClosed()) # for holes processing "forward" means CCW self.assertFalse(PathOpTools.isWireClockwise(wire)) y = 4 # offset works in both directions x = 4 * math.cos(math.pi / 6) self.assertLines(wire.Edges, False, [ Vector(0, 4, 0), Vector(-x, -2, 0), Vector(x, -2, 0), Vector(0, 4, 0) ])
def test01(self): """Verify isWireClockwise for single edge circle wires.""" self.assertTrue( PathOpTools.isWireClockwise( Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1)))) self.assertFalse( PathOpTools.isWireClockwise( Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1))))
def test04(self): '''Verify isWireClockwise for unoriented wires.''' e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 0, 180) e3 = Part.makeLine(e0.valueAt(e0.FirstParameter), e0.valueAt(e0.LastParameter)) self.assertTrue(PathOpTools.isWireClockwise(Part.Wire([e0, e3]))) e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 0, 180) e3 = Part.makeLine(e0.valueAt(e0.FirstParameter), e0.valueAt(e0.LastParameter)) self.assertFalse(PathOpTools.isWireClockwise(Part.Wire([e0, e3])))
def test03(self): '''Verify isWireClockwise for two edge wires with an arc.''' e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 0, 180) e2 = Part.makeLine(e0.valueAt(e0.LastParameter), e0.valueAt(e0.FirstParameter)) self.assertTrue(PathOpTools.isWireClockwise(Part.Wire([e0, e2]))) e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 0, 180) e2 = Part.makeLine(e0.valueAt(e0.LastParameter), e0.valueAt(e0.FirstParameter)) self.assertFalse(PathOpTools.isWireClockwise(Part.Wire([e0, e2])))
def test02(self): '''Verify isWireClockwise for two half circle wires.''' e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 0, 180) e1 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 180, 360) self.assertTrue(PathOpTools.isWireClockwise(Part.Wire([e0, e1]))) e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 0, 180) e1 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 180, 360) self.assertFalse(PathOpTools.isWireClockwise(Part.Wire([e0, e1])))
def test00(self): '''Verify isWireClockwise for polygon wires.''' pa = Vector(1, 1, 0) pb = Vector(1, 5, 0) pc = Vector(5, 5, 0) pd = Vector(5, 1, 0) self.assertTrue(PathOpTools.isWireClockwise(makeWire([pa, pb, pc, pd]))) self.assertFalse(PathOpTools.isWireClockwise(makeWire([pa, pd, pc, pb])))
def test02(self): """Verify isWireClockwise for two half circle wires.""" e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 0, 180) e1 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 180, 360) self.assertTrue(PathOpTools.isWireClockwise(Part.Wire([e0, e1]))) e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 0, 180) e1 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 180, 360) self.assertFalse(PathOpTools.isWireClockwise(Part.Wire([e0, e1])))
def test04(self): """Verify isWireClockwise for unoriented wires.""" e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 0, 180) e3 = Part.makeLine(e0.valueAt(e0.FirstParameter), e0.valueAt(e0.LastParameter)) self.assertTrue(PathOpTools.isWireClockwise(Part.Wire([e0, e3]))) e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 0, 180) e3 = Part.makeLine(e0.valueAt(e0.FirstParameter), e0.valueAt(e0.LastParameter)) self.assertFalse(PathOpTools.isWireClockwise(Part.Wire([e0, e3])))
def test12(self): '''Check offsetting a circular hole by the radius or more makes the hole vanish.''' obj = doc.getObjectsByLabel('offset-circle')[0] small = getWireInside(obj) self.assertRoughly(10, small.Edges[0].Curve.Radius) wire = PathOpTools.offsetWire(small, obj.Shape, 10, True) self.assertIsNone(wire) wire = PathOpTools.offsetWire(small, obj.Shape, 15, True) self.assertIsNone(wire)
def test12(self): """Check offsetting a circular hole by the radius or more makes the hole vanish.""" obj = doc.getObjectsByLabel("offset-circle")[0] small = getWireInside(obj) self.assertRoughly(10, small.Edges[0].Curve.Radius) wire = PathOpTools.offsetWire(small, obj.Shape, 10, True) self.assertIsNone(wire) wire = PathOpTools.offsetWire(small, obj.Shape, 15, True) self.assertIsNone(wire)
def test03(self): """Verify isWireClockwise for two edge wires with an arc.""" e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1), 0, 180) e2 = Part.makeLine(e0.valueAt(e0.LastParameter), e0.valueAt(e0.FirstParameter)) self.assertTrue(PathOpTools.isWireClockwise(Part.Wire([e0, e2]))) e0 = Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1), 0, 180) e2 = Part.makeLine(e0.valueAt(e0.LastParameter), e0.valueAt(e0.FirstParameter)) self.assertFalse(PathOpTools.isWireClockwise(Part.Wire([e0, e2])))
def test00(self): """Verify isWireClockwise for polygon wires.""" pa = Vector(1, 1, 0) pb = Vector(1, 5, 0) pc = Vector(5, 5, 0) pd = Vector(5, 1, 0) self.assertTrue(PathOpTools.isWireClockwise(makeWire([pa, pb, pc, pd]))) self.assertFalse( PathOpTools.isWireClockwise(makeWire([pa, pd, pc, pb])))
def test22(self): """Check offsetting a body wire succeeds.""" obj = doc.getObjectsByLabel("offset-edge")[0] big = getWireOutside(obj) # sanity check y = 20 x = 20 * math.cos(math.pi / 6) self.assertLines( big.Edges, False, [ Vector(0, y, 0), Vector(-x, -y / 2, 0), Vector(x, -y / 2, 0), Vector(0, y, 0), ], ) wire = PathOpTools.offsetWire(big, obj.Shape, 5, True) self.assertIsNotNone(wire) self.assertEqual(6, len(wire.Edges)) lastAngle = None refAngle = math.pi / 3 for e in wire.Edges: if Part.Circle == type(e.Curve): self.assertRoughly(5, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) else: self.assertRoughly(34.641, e.Length, 0.001) begin = e.Vertexes[0].Point end = e.Vertexes[1].Point v = end - begin angle = PathGeom.getAngle(v) if PathGeom.isRoughly(0, angle) or PathGeom.isRoughly( math.pi, math.fabs(angle)): if lastAngle: self.assertRoughly(-refAngle, lastAngle) elif PathGeom.isRoughly(+refAngle, angle): if lastAngle: self.assertRoughly(math.pi, math.fabs(lastAngle)) elif PathGeom.isRoughly(-refAngle, angle): if lastAngle: self.assertRoughly(+refAngle, lastAngle) else: self.assertIsNone("%s: angle=%s" % (type(e.Curve), angle)) lastAngle = angle self.assertTrue(PathOpTools.isWireClockwise(wire))
def opExecute(self, obj): PathLog.track(obj.Label) (depth, offset) = toolDepthAndOffset(obj.Width.Value, obj.ExtraDepth.Value, self.tool) PathLog.track(obj.Label, depth, offset) self.basewires = [] self.adjusted_basewires = [] wires = [] for base, subs in obj.Base: edges = [] basewires = [] for f in subs: sub = base.Shape.getElement(f) if type(sub) == Part.Edge: edges.append(sub) elif sub.Wires: basewires.extend(sub.Wires) else: basewires.append(Part.Wire(sub.Edges)) self.edges = edges for edgelist in Part.sortEdges(edges): basewires.append(Part.Wire(edgelist)) self.basewires.extend(basewires) for w in self.adjustWirePlacement(obj, base, basewires): self.adjusted_basewires.append(w) wire = PathOpTools.offsetWire(w, base.Shape, offset, True) if wire: wires.append(wire) self.wires = wires self.buildpathocc(obj, wires, [depth], True)
def test11(self): """Check offsetting a circular hole.""" obj = doc.getObjectsByLabel("offset-circle")[0] small = getWireInside(obj) self.assertRoughly(10, small.Edges[0].Curve.Radius) wire = PathOpTools.offsetWire(small, obj.Shape, 3, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(7, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, 1), wire.Edges[0].Curve.Axis) wire = PathOpTools.offsetWire(small, obj.Shape, 9.9, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(0.1, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, 1), wire.Edges[0].Curve.Axis)
def test13(self): """Check offsetting a cylinder succeeds.""" obj = doc.getObjectsByLabel("offset-circle")[0] big = getWireOutside(obj) self.assertRoughly(20, big.Edges[0].Curve.Radius) wire = PathOpTools.offsetWire(big, obj.Shape, 10, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(30, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, -1), wire.Edges[0].Curve.Axis) wire = PathOpTools.offsetWire(big, obj.Shape, 20, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(40, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, -1), wire.Edges[0].Curve.Axis)
def test11(self): '''Check offsetting a circular hole.''' obj = doc.getObjectsByLabel('offset-circle')[0] small = getWireInside(obj) self.assertRoughly(10, small.Edges[0].Curve.Radius) wire = PathOpTools.offsetWire(small, obj.Shape, 3, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(7, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, 1), wire.Edges[0].Curve.Axis) wire = PathOpTools.offsetWire(small, obj.Shape, 9.9, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(0.1, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, 1), wire.Edges[0].Curve.Axis)
def test13(self): '''Check offsetting a cylinder succeeds.''' obj = doc.getObjectsByLabel('offset-circle')[0] big = getWireOutside(obj) self.assertRoughly(20, big.Edges[0].Curve.Radius) wire = PathOpTools.offsetWire(big, obj.Shape, 10, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(30, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, -1), wire.Edges[0].Curve.Axis) wire = PathOpTools.offsetWire(big, obj.Shape, 20, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(40, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, -1), wire.Edges[0].Curve.Axis)
def test35(self): '''Check offsetting a cylindrical hole.''' obj = doc.getObjectsByLabel('circle-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(1, len(wire.Edges)) edge = wire.Edges[0] self.assertCoincide(Vector(), edge.Curve.Center) self.assertCoincide(Vector(0, 0, +1), edge.Curve.Axis) self.assertRoughly(27, edge.Curve.Radius) # the other way around everything's the same except the axis is negative wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(1, len(wire.Edges)) edge = wire.Edges[0] self.assertCoincide(Vector(), edge.Curve.Center) self.assertCoincide(Vector(0, 0, -1), edge.Curve.Axis) self.assertRoughly(27, edge.Curve.Radius)
def test32(self): """Check offsetting a box.""" obj = doc.getObjectsByLabel("square-cut")[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, True) self.assertEqual(8, len(wire.Edges)) self.assertEqual( 4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual( 4, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) for e in wire.Edges: if Part.Line == type(e.Curve): if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertEqual(40, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertEqual(60, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) self.assertTrue(PathOpTools.isWireClockwise(wire)) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, False) self.assertEqual(8, len(wire.Edges)) self.assertEqual( 4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) self.assertEqual( 4, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) for e in wire.Edges: if Part.Line == type(e.Curve): if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertEqual(40, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertEqual(60, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) self.assertFalse(PathOpTools.isWireClockwise(wire))
def test37(self): '''Check offsetting a triangular holee.''' obj = doc.getObjectsByLabel('triangle-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(3, len(wire.Edges)) self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) length = 48 * math.sin(math.radians(60)) for e in wire.Edges: self.assertRoughly(length, e.Length) self.assertFalse(PathOpTools.isWireClockwise(wire)) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(3, len(wire.Edges)) self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) for e in wire.Edges: self.assertRoughly(length, e.Length) self.assertTrue(PathOpTools.isWireClockwise(wire))
def test20(self): '''Check offsetting hole wire succeeds.''' obj = doc.getObjectsByLabel('offset-edge')[0] small = getWireInside(obj) # sanity check y = 10 x = 10 * math.cos(math.pi/6) self.assertLines(small.Edges, False, [Vector(0, y, 0), Vector(-x, -y/2, 0), Vector(x, -y/2, 0), Vector(0, y, 0)]) wire = PathOpTools.offsetWire(small, obj.Shape, 3, True) self.assertIsNotNone(wire) self.assertEqual(3, len(wire.Edges)) self.assertTrue(wire.isClosed()) # for holes processing "forward" means CCW self.assertFalse(PathOpTools.isWireClockwise(wire)) y = 4 # offset works in both directions x = 4 * math.cos(math.pi/6) self.assertLines(wire.Edges, False, [Vector(0, 4, 0), Vector(-x, -2, 0), Vector(x, -2, 0), Vector(0, 4, 0)])
def test43(self): """Check offsetting multiple backwards outside edges.""" # This is exactly the same as test32, except that the wire is flipped to make # sure the input orientation doesn't matter obj = doc.getObjectsByLabel("offset-edge")[0] w = getWireOutside(obj) length = 40 * math.cos(math.pi / 6) # let's offset the other two legs lEdges = [ e for e in w.Edges if not PathGeom.isRoughly( e.Vertexes[0].Point.y, e.Vertexes[1].Point.y) ] self.assertEqual(2, len(lEdges)) w = PathGeom.flipWire(Part.Wire(lEdges)) wire = PathOpTools.offsetWire(w, obj.Shape, 2, True) x = length / 2 + 2 * math.cos(math.pi / 6) y = -10 + 2 * math.sin(math.pi / 6) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) self.assertCoincide(Vector(0, 0, -1), rEdges[0].Curve.Axis) # offset the other way wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) self.assertCoincide(Vector(0, 0, +1), rEdges[0].Curve.Axis)
def test21(self): '''Check offsetting hole wire for more than it's size makes hole vanish.''' obj = doc.getObjectsByLabel('offset-edge')[0] small = getWireInside(obj) # sanity check y = 10 x = 10 * math.cos(math.pi/6) self.assertLines(small.Edges, False, [Vector(0, y, 0), Vector(-x, -y/2, 0), Vector(x, -y/2, 0), Vector(0, y, 0)]) wire = PathOpTools.offsetWire(small, obj.Shape, 5, True) self.assertIsNone(wire)
def test35(self): """Check offsetting a cylindrical hole.""" obj = doc.getObjectsByLabel("circle-cut")[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(1, len(wire.Edges)) edge = wire.Edges[0] self.assertCoincide(Vector(), edge.Curve.Center) self.assertCoincide(Vector(0, 0, +1), edge.Curve.Axis) self.assertRoughly(27, edge.Curve.Radius) # the other way around everything's the same except the axis is negative wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(1, len(wire.Edges)) edge = wire.Edges[0] self.assertCoincide(Vector(), edge.Curve.Center) self.assertCoincide(Vector(0, 0, -1), edge.Curve.Axis) self.assertRoughly(27, edge.Curve.Radius)
def test42(self): """Check offsetting multiple outside edges.""" obj = doc.getObjectsByLabel("offset-edge")[0] obj.Shape.tessellate(0.01) doc.recompute() w = getWireOutside(obj) length = 40 * math.cos(math.pi / 6) # let's offset the other two legs lEdges = [ e for e in w.Edges if not PathGeom.isRoughly( e.Vertexes[0].Point.y, e.Vertexes[1].Point.y) ] self.assertEqual(2, len(lEdges)) wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, True) x = length / 2 + 2 * math.cos(math.pi / 6) y = -10 + 2 * math.sin(math.pi / 6) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) self.assertCoincide(Vector(0, 0, -1), rEdges[0].Curve.Axis) # offset the other way wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) self.assertCoincide(Vector(0, 0, +1), rEdges[0].Curve.Axis)
def test42(self): '''Check offsetting multiple outside edges.''' obj = doc.getObjectsByLabel('offset-edge')[0] obj.Shape.tessellate(0.01) doc.recompute() w = getWireOutside(obj) length = 40 * math.cos(math.pi/6) # let's offset the other two legs lEdges = [e for e in w.Edges if not PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y)] self.assertEqual(2, len(lEdges)) wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, True) x = length/2 + 2 * math.cos(math.pi/6) y = -10 + 2 * math.sin(math.pi/6) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) self.assertCoincide(Vector(0, 0, -1), rEdges[0].Curve.Axis) #offset the other way wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) self.assertCoincide(Vector(0, 0, +1), rEdges[0].Curve.Axis)
def test22(self): '''Check offsetting a body wire succeeds.''' obj = doc.getObjectsByLabel('offset-edge')[0] big = getWireOutside(obj) # sanity check y = 20 x = 20 * math.cos(math.pi/6) self.assertLines(big.Edges, False, [Vector(0, y, 0), Vector(-x, -y/2, 0), Vector(x, -y/2, 0), Vector(0, y, 0)]) wire = PathOpTools.offsetWire(big, obj.Shape, 5, True) self.assertIsNotNone(wire) self.assertEqual(6, len(wire.Edges)) lastAngle = None refAngle = math.pi / 3 for e in wire.Edges: if Part.Circle == type(e.Curve): self.assertRoughly(5, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) else: self.assertRoughly(34.641, e.Length, 0.001) begin = e.Vertexes[0].Point end = e.Vertexes[1].Point v = end - begin angle = PathGeom.getAngle(v) if PathGeom.isRoughly(0, angle) or PathGeom.isRoughly(math.pi, math.fabs(angle)): if lastAngle: self.assertRoughly(-refAngle, lastAngle) elif PathGeom.isRoughly(+refAngle, angle): if lastAngle: self.assertRoughly(math.pi, math.fabs(lastAngle)) elif PathGeom.isRoughly(-refAngle, angle): if lastAngle: self.assertRoughly(+refAngle, lastAngle) else: self.assertIsNone("%s: angle=%s" % (type(e.Curve), angle)) lastAngle = angle self.assertTrue(PathOpTools.isWireClockwise(wire))
def test37(self): """Check offsetting a triangular holee.""" obj = doc.getObjectsByLabel("triangle-cut")[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(3, len(wire.Edges)) self.assertEqual( 3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) length = 48 * math.sin(math.radians(60)) for e in wire.Edges: self.assertRoughly(length, e.Length) self.assertFalse(PathOpTools.isWireClockwise(wire)) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(3, len(wire.Edges)) self.assertEqual( 3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) for e in wire.Edges: self.assertRoughly(length, e.Length) self.assertTrue(PathOpTools.isWireClockwise(wire))
def test50(self): """Orient an already oriented wire""" p0 = Vector() p1 = Vector(1, 2, 3) p2 = Vector(2, 3, 4) pts = [p0, p1, p2] e0 = Part.Edge(Part.LineSegment(p0, p1)) e1 = Part.Edge(Part.LineSegment(p1, p2)) wire = PathOpTools.orientWire(Part.Wire([e0, e1])) wirePts = wireMarkers(wire) self.assertPointsMatch(wirePts, pts)
def test51(self): """Orient a potentially misoriented wire""" p0 = Vector() p1 = Vector(1, 2, 3) p2 = Vector(2, 3, 4) pts = [p0, p1, p2] e0p = Part.Edge(Part.LineSegment(p0, p1)) e0m = Part.Edge(Part.LineSegment(p1, p0)) e1p = Part.Edge(Part.LineSegment(p1, p2)) e1m = Part.Edge(Part.LineSegment(p2, p1)) wire = PathOpTools.orientWire(Part.Wire([e0p, e1p])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0p, e1m])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0m, e1p])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0m, e1m])) self.assertPointsMatch(wireMarkers(wire), pts)
def buildpathocc(self, obj, wires, zValues, relZ=False, forward=True, start_idx=0): '''buildpathocc(obj, wires, zValues, relZ=False) ... internal helper function to generate engraving commands.''' PathLog.track(obj.Label, len(wires), zValues) for wire in wires: offset = wire # reorder the wire if hasattr(obj, 'StartVertex'): start_idx = obj.StartVertex edges = copy.copy(PathOpTools.orientWire(offset, forward).Edges) edges = Part.sortEdges(edges)[0]; last = None for z in zValues: PathLog.debug(z) if last: self.appendCommand(Path.Command('G1', {'X': last.x, 'Y': last.y, 'Z': last.z}), z, relZ, self.vertFeed) first = True if start_idx > len(edges)-1: start_idx = len(edges)-1 edges = edges[start_idx:] + edges[:start_idx] for edge in edges: PathLog.debug("points: {} -> {}".format(edge.Vertexes[0].Point, edge.Vertexes[-1].Point)) PathLog.debug("valueat {} -> {}".format(edge.valueAt(edge.FirstParameter), edge.valueAt(edge.LastParameter))) if first and (not last or not wire.isClosed()): PathLog.debug('processing first edge entry') # we set the first move to our first point last = edge.Vertexes[0].Point self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid})) self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'F': self.horizRapid})) self.commandlist.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid})) self.appendCommand(Path.Command('G1', {'X': last.x, 'Y': last.y, 'Z': last.z}), z, relZ, self.vertFeed) first = False if PathGeom.pointsCoincide(last, edge.valueAt(edge.FirstParameter)): #if PathGeom.pointsCoincide(last, edge.Vertexes[0].Point): for cmd in PathGeom.cmdsForEdge(edge): self.appendCommand(cmd, z, relZ, self.horizFeed) last = edge.Vertexes[-1].Point else: for cmd in PathGeom.cmdsForEdge(edge, True): self.appendCommand(cmd, z, relZ, self.horizFeed) last = edge.Vertexes[0].Point self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
def test45(self): """Check offsetting a single inside edge not forward.""" obj = doc.getObjectsByLabel("offset-edge")[0] w = getWireInside(obj) length = 20 * math.cos(math.pi / 6) for e in w.Edges: self.assertRoughly(length, e.Length) # let's offset the horizontal edge for starters hEdges = [ e for e in w.Edges if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y) ] x = length / 2 y = -5 self.assertEqual(1, len(hEdges)) edge = hEdges[0] self.assertCoincide(Vector(-x, y, 0), edge.Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), edge.Vertexes[1].Point) wire = PathOpTools.offsetWire(Part.Wire([edge]), obj.Shape, 2, False) self.assertEqual(1, len(wire.Edges)) y = y + 2 self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[1].Point) # make sure we get the same result even if the edge is oriented the other way edge = PathGeom.flipEdge(edge) wire = PathOpTools.offsetWire(Part.Wire([edge]), obj.Shape, 2, False) self.assertEqual(1, len(wire.Edges)) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[1].Point)
def test36(self): '''Check offsetting a square hole.''' obj = doc.getObjectsByLabel('square-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(4, len(wire.Edges)) self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) for e in wire.Edges: if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertRoughly(34, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertRoughly(54, e.Length) self.assertFalse(PathOpTools.isWireClockwise(wire)) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(4, len(wire.Edges)) self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) for e in wire.Edges: if PathGeom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertRoughly(34, e.Length) if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertRoughly(54, e.Length) self.assertTrue(PathOpTools.isWireClockwise(wire))
def test47(self): '''Check offsetting multiple backwards inside edges.''' # This is exactly the same as test36 except that the wire is flipped to make # sure it's orientation doesn't matter obj = doc.getObjectsByLabel('offset-edge')[0] w = getWireInside(obj) length = 20 * math.cos(math.pi / 6) # let's offset the other two legs lEdges = [ e for e in w.Edges if not PathGeom.isRoughly( e.Vertexes[0].Point.y, e.Vertexes[1].Point.y) ] self.assertEqual(2, len(lEdges)) w = PathGeom.flipWire(Part.Wire(lEdges)) wire = PathOpTools.offsetWire(w, obj.Shape, 2, True) x = length / 2 - 2 * math.cos(math.pi / 6) y = -5 - 2 * math.sin(math.pi / 6) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges)) #offset the other way wire = PathOpTools.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] self.assertEqual(0, len(rEdges))
def test41(self): '''Check offsetting a single outside edge not forward.''' obj = doc.getObjectsByLabel('offset-edge')[0] w = getWireOutside(obj) length = 40 * math.cos(math.pi / 6) for e in w.Edges: self.assertRoughly(length, e.Length) # let's offset the horizontal edge for starters hEdges = [ e for e in w.Edges if PathGeom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y) ] x = length / 2 y = -10 self.assertEqual(1, len(hEdges)) edge = hEdges[0] self.assertCoincide(Vector(-x, y, 0), edge.Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), edge.Vertexes[1].Point) wire = PathOpTools.offsetWire(Part.Wire([edge]), obj.Shape, 5, False) self.assertEqual(1, len(wire.Edges)) y = y - 5 self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[1].Point) # make sure we get the same result on a reversed edge edge = PathGeom.flipEdge(edge) wire = PathOpTools.offsetWire(Part.Wire([edge]), obj.Shape, 5, False) self.assertEqual(1, len(wire.Edges)) self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[1].Point)
def test21(self): '''Check offsetting hole wire for more than it's size makes hole vanish.''' obj = doc.getObjectsByLabel('offset-edge')[0] small = getWireInside(obj) # sanity check y = 10 x = 10 * math.cos(math.pi / 6) self.assertLines(small.Edges, False, [ Vector(0, y, 0), Vector(-x, -y / 2, 0), Vector(x, -y / 2, 0), Vector(0, y, 0) ]) wire = PathOpTools.offsetWire(small, obj.Shape, 5, True) self.assertIsNone(wire)
def opExecute(self, obj): PathLog.track(obj.Label) (depth, offset) = toolDepthAndOffset(obj.Width.Value, obj.ExtraDepth.Value, self.tool) PathLog.track(obj.Label, depth, offset) self.basewires = [] self.adjusted_basewires = [] wires = [] for base, subs in obj.Base: edges = [] basewires = [] for f in subs: sub = base.Shape.getElement(f) if type(sub) == Part.Edge: edges.append(sub) elif sub.Wires: basewires.extend(sub.Wires) else: basewires.append(Part.Wire(sub.Edges)) self.edges = edges for edgelist in Part.sortEdges(edges): basewires.append(Part.Wire(edgelist)) self.basewires.extend(basewires) for w in basewires: self.adjusted_basewires.append(w) wire = PathOpTools.offsetWire(w, base.Shape, offset, True) if wire: wires.append(wire) zValues = [] z = 0 if obj.StepDown.Value != 0: while z + obj.StepDown.Value < depth: z = z + obj.StepDown.Value zValues.append(z) zValues.append(depth) PathLog.track(obj.Label, depth, zValues) self.wires = wires self.buildpathocc(obj, wires, zValues, True) # the last command is a move to clearance, which is automatically added by PathOp if self.commandlist: self.commandlist.pop()
def test15(self): '''Check offsetting a cylinder with Placement.''' obj = doc.getObjectsByLabel('offset-placement')[0] wires = [w for w in obj.Shape.Wires if 1 == len(w.Edges) and PathGeom.isRoughly(0, w.Edges[0].Vertexes[0].Point.z)] self.assertEqual(2, len(wires)) w = wires[0] if wires[0].BoundBox.isInside(wires[1].BoundBox) else wires[1] self.assertRoughly(20, w.Edges[0].Curve.Radius) # make sure there is a placement and I didn't mess up the model self.assertFalse(PathGeom.pointsCoincide(Vector(), w.Edges[0].Placement.Base)) wire = PathOpTools.offsetWire(w, obj.Shape, 2, True) self.assertIsNotNone(wire) self.assertEqual(1, len(wire.Edges)) self.assertRoughly(22, wire.Edges[0].Curve.Radius) self.assertCoincide(Vector(0, 0, 0), wire.Edges[0].Curve.Center) self.assertCoincide(Vector(0, 0, -1), wire.Edges[0].Curve.Axis)
def test52(self): """Orient a potentially misoriented longer wire""" p0 = Vector() p1 = Vector(1, 2, 3) p2 = Vector(4, 5, 6) p3 = Vector(7, 8, 9) pts = [p0, p1, p2, p3] e0p = Part.Edge(Part.LineSegment(p0, p1)) e0m = Part.Edge(Part.LineSegment(p1, p0)) e1p = Part.Edge(Part.LineSegment(p1, p2)) e1m = Part.Edge(Part.LineSegment(p2, p1)) e2p = Part.Edge(Part.LineSegment(p2, p3)) e2m = Part.Edge(Part.LineSegment(p3, p2)) wire = PathOpTools.orientWire(Part.Wire([e0p, e1p, e2p])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0p, e1m, e2p])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0m, e1p, e2p])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0m, e1m, e2p])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0p, e1p, e2m])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0p, e1m, e2m])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0m, e1p, e2m])) self.assertPointsMatch(wireMarkers(wire), pts) wire = PathOpTools.orientWire(Part.Wire([e0m, e1m, e2m])) self.assertPointsMatch(wireMarkers(wire), pts)
def buildpathocc(self, obj, wires, zValues, relZ=False): '''buildpathocc(obj, wires, zValues, relZ=False) ... internal helper function to generate engraving commands.''' PathLog.track(obj.Label, len(wires), zValues) for wire in wires: offset = wire # reorder the wire if hasattr(obj, 'StartVertex'): offset = DraftGeomUtils.rebaseWire(offset, obj.StartVertex) edges = copy.copy(PathOpTools.orientWire(offset).Edges) last = None for z in zValues: if last: self.appendCommand(Path.Command('G1', {'X': last.x, 'Y': last.y, 'Z': last.z}), z, relZ, self.vertFeed) first = True for edge in edges: if first and (not last or not wire.isClosed()): # we set the first move to our first point last = edge.Vertexes[0].Point self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid})) self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'F': self.horizRapid})) self.commandlist.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid})) self.appendCommand(Path.Command('G1', {'Z': last.z}), z, relZ, self.vertFeed) first = False if PathGeom.pointsCoincide(last, edge.Vertexes[0].Point): for cmd in PathGeom.cmdsForEdge(edge): self.appendCommand(cmd, z, relZ, self.horizFeed) last = edge.Vertexes[-1].Point else: for cmd in PathGeom.cmdsForEdge(edge, True): self.appendCommand(cmd, z, relZ, self.horizFeed) last = edge.Vertexes[0].Point self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
def test01(self): '''Verify isWireClockwise for single edge circle wires.''' self.assertTrue(PathOpTools.isWireClockwise(Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, -1)))) self.assertFalse(PathOpTools.isWireClockwise(Part.makeCircle(5, Vector(1, 2, 3), Vector(0, 0, +1))))