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 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 test33(self): '''Check offsetting a triangle.''' obj = doc.getObjectsByLabel('triangle-cut')[0] wire = PathOpTools.offsetWire(getWire(obj.Tool), getPositiveShape(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 = 60 * math.sin(math.radians(60)) for e in wire.Edges: if Part.Line == type(e.Curve): self.assertRoughly(length, e.Length) if Part.Circle == type(e.Curve): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) # change offset orientation wire = PathOpTools.offsetWire(getWire(obj.Tool), getPositiveShape(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(3, 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 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 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 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 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 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 = [] # pylint: disable=attribute-defined-outside-init self.adjusted_basewires = [] # pylint: disable=attribute-defined-outside-init 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 # pylint: disable=attribute-defined-outside-init for edgelist in Part.sortEdges(edges): basewires.append(Part.Wire(edgelist)) self.basewires.extend(basewires) # Set default value side = ["Outside"] for w in basewires: self.adjusted_basewires.append(w) wire = PathOpTools.offsetWire(w, base.Shape, offset, True, side) if wire: wires.append(wire) # Save Outside or Inside obj.Side = side[0] # Set direction of op forward = True if obj.Direction == 'CCW': forward = False 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) if obj.EntryPoint < 0: obj.EntryPoint = 0; self.wires = wires # pylint: disable=attribute-defined-outside-init self.buildpathocc(obj, wires, zValues, True, forward, obj.EntryPoint) # the last command is a move to clearance, which is automatically added by PathOp if self.commandlist: self.commandlist.pop()
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 opExecute(self, obj): PathLog.track(obj.Label) try: (depth, offset) = toolDepthAndOffset(obj.Width.Value, obj.ExtraDepth.Value, self.tool) except ValueError as e: msg = "{} \n No path will be generated".format(e) raise ValueError(msg) # QtGui.QMessageBox.information(None, "Tool Error", msg) # return PathLog.track(obj.Label, depth, offset) self.basewires = [] # pylint: disable=attribute-defined-outside-init self.adjusted_basewires = [] # pylint: disable=attribute-defined-outside-init 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 # pylint: disable=attribute-defined-outside-init 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) #, obj.Side) if wire: wires.append(wire) # # Save Outside or Inside # obj.Side = side[0] # Set direction of op forward = (obj.Direction == 'CW') 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) if obj.EntryPoint < 0: obj.EntryPoint = 0 self.wires = wires # pylint: disable=attribute-defined-outside-init self.buildpathocc(obj, wires, zValues, True, forward, obj.EntryPoint)
def opExecute(self, obj): PathLog.track(obj.Label) if not hasattr(self, 'printInfo'): self.printInfo = True try: (depth, offset, extraOffset, suppressInfo) = toolDepthAndOffset(obj.Width.Value, obj.ExtraDepth.Value, self.tool, self.printInfo) self.printInfo = not suppressInfo except ValueError as e: msg = "{} \n No path will be generated".format(e) raise ValueError(msg) # QtGui.QMessageBox.information(None, "Tool Error", msg) # return PathLog.track(obj.Label, depth, offset) self.basewires = [] # pylint: disable=attribute-defined-outside-init self.adjusted_basewires = [] # pylint: disable=attribute-defined-outside-init wires = [] for base, subs in obj.Base: edges = [] basewires = [] max_h = -99999 radius_top = 0 radius_bottom = 0 for f in subs: sub = base.Shape.getElement(f) if type(sub) == Part.Edge: # Edge edges.append(sub) elif type(sub) == Part.Face and sub.normalAt( 0, 0) != FreeCAD.Vector(0, 0, 1): # Angled face # If an angled face is selected, the lower edge is projected to the height of the upper edge, # to simulate an edge # Find z value of upper edge for edge in sub.Edges: for p0 in edge.Vertexes: if p0.Point.z > max_h: max_h = p0.Point.z # Find biggest radius for top/bottom for edge in sub.Edges: if Part.Circle == type(edge.Curve): if edge.Vertexes[0].Point.z == max_h: if edge.Curve.Radius > radius_top: radius_top = edge.Curve.Radius else: if edge.Curve.Radius > radius_bottom: radius_bottom = edge.Curve.Radius # Search for lower edge and raise it to height of upper edge for edge in sub.Edges: if Part.Circle == type(edge.Curve): # Edge is a circle if edge.Vertexes[0].Point.z < max_h: if edge.Closed: # Circle # New center center = FreeCAD.Vector( edge.Curve.Center.x, edge.Curve.Center.y, max_h) new_edge = Part.makeCircle( edge.Curve.Radius, center, FreeCAD.Vector(0, 0, 1)) edges.append(new_edge) # Modify offset for inner angled faces if radius_bottom < radius_top: offset -= 2 * extraOffset break else: # Arc if edge.Vertexes[ 0].Point.z == edge.Vertexes[ 1].Point.z: # Arc vertexes are on same layer l1 = math.sqrt( (edge.Vertexes[0].Point.x - edge.Curve.Center.x)**2 + (edge.Vertexes[0].Point.y - edge.Curve.Center.y)**2) l2 = math.sqrt( (edge.Vertexes[1].Point.x - edge.Curve.Center.x)**2 + (edge.Vertexes[1].Point.y - edge.Curve.Center.y)**2) # New center center = FreeCAD.Vector( edge.Curve.Center.x, edge.Curve.Center.y, max_h) # Calculate angles based on x-axis (0 - PI/2) start_angle = math.acos( (edge.Vertexes[0].Point.x - edge.Curve.Center.x) / l1) end_angle = math.acos( (edge.Vertexes[1].Point.x - edge.Curve.Center.x) / l2) # Angles are based on x-axis (Mirrored on x-axis) -> negative y value means negative angle if edge.Vertexes[ 0].Point.y < edge.Curve.Center.y: start_angle *= -1 if edge.Vertexes[ 1].Point.y < edge.Curve.Center.y: end_angle *= -1 # Create new arc new_edge = Part.ArcOfCircle( Part.Circle( center, FreeCAD.Vector(0, 0, 1), edge.Curve.Radius), start_angle, end_angle).toShape() edges.append(new_edge) # Modify offset for inner angled faces if radius_bottom < radius_top: offset -= 2 * extraOffset break else: # Line if edge.Vertexes[0].Point.z == edge.Vertexes[ 1].Point.z and edge.Vertexes[ 0].Point.z < max_h: new_edge = Part.Edge( Part.LineSegment( FreeCAD.Vector( edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, max_h), FreeCAD.Vector( edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y, max_h))) edges.append(new_edge) elif sub.Wires: basewires.extend(sub.Wires) else: # Flat face basewires.append(Part.Wire(sub.Edges)) self.edges = edges # pylint: disable=attribute-defined-outside-init for edgelist in Part.sortEdges(edges): basewires.append(Part.Wire(edgelist)) self.basewires.extend(basewires) # Set default side side = ["Outside"] for w in basewires: self.adjusted_basewires.append(w) wire = PathOpTools.offsetWire(w, base.Shape, offset, True, side) if wire: wires.append(wire) # Set direction of op forward = (obj.Direction == 'CW') # Set value of side obj.Side = side[0] # Check side extra for angled faces if radius_top > radius_bottom: obj.Side = "Inside" 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) if obj.EntryPoint < 0: obj.EntryPoint = 0 self.wires = wires # pylint: disable=attribute-defined-outside-init self.buildpathocc(obj, wires, zValues, True, forward, obj.EntryPoint)