Added flipping of edge to PathGeom.

This commit is contained in:
Markus Lampert
2018-06-21 23:25:26 -07:00
parent 8130b57945
commit d101111f64
3 changed files with 111 additions and 13 deletions

View File

@@ -23,10 +23,10 @@
# ***************************************************************************
import FreeCAD
import math
import Part
import Path
import PathScripts.PathLog as PathLog
import math
from FreeCAD import Vector
from PySide import QtCore
@@ -455,3 +455,21 @@ def removeDuplicateEdges(wire):
unique.append(e)
return Part.Wire(unique)
def flipEdge(edge):
'''flipEdge(edge)
Flips given edge around so the new Vertexes[0] was the old Vertexes[-1] and vice versa, without changing the shape.
Currently only lines, line segments, circles and arcs are supported.'''
if Part.Line == type(edge.Curve) and not edge.Vertexes:
return Part.Edge(Part.Line(edge.valueAt(edge.LastParameter), edge.valueAt(edge.FirstParameter)))
elif Part.Line == type(edge.Curve) or Part.LineSegment == type(edge.Curve):
return Part.Edge(Part.LineSegment(edge.Vertexes[-1].Point, edge.Vertexes[0].Point))
elif Part.Circle == type(edge.Curve):
return Part.makeCircle(edge.Curve.Radius, edge.Curve.Center, -edge.Curve.Axis, -math.degrees(edge.LastParameter), -math.degrees(edge.FirstParameter))
elif Part.BSplineCurve == type(edge.Curve):
spline = edge.Curve
poles = [p for p in reversed(spline.getPoles())]
weights = [w for w in reversed(spline.getWeights())]
degree = spline.Degree
return Part.Edge(Part.BSplineCurve(poles, degree=degree, weights=weights))

View File

@@ -135,3 +135,27 @@ class PathTestBase(unittest.TestCase):
q2=FreeCAD.Units.Quantity(s2)
self.assertEqual(q1.UserString, q2.UserString)
def assertEdgeShapesMatch(self,e1,e2):
"""Verify that 2 edges have the same start/end points and the mid point matches too."""
self.assertEqual(type(e1.Curve), type(e2.Curve))
self.assertEqual(len(e1.Vertexes), len(e2.Vertexes))
if not e1.Vertexes:
self.assertEqual(Part.Line, type(e1.Curve))
k1 = e1.valueAt(e1.LastParameter) - e1.valueAt(e1.FirstParameter)
k2 = e2.valueAt(e2.LastParameter) - e2.valueAt(e2.FirstParameter)
self.assertCoincide(k1, -k2)
elif 1 == len(e1.Vertexes):
self.assertEqual(Part.Circle, type(e1.Curve))
self.assertRoughly(e1.Curve.Radius, e2.Curve.Radius)
self.assertCoincide(e1.Curve.Center, e2.Curve.Center)
self.assertCoincide(e1.Curve.Axis, -e2.Curve.Axis)
else:
if PathGeom.pointsCoincide(e1.Vertexes[0].Point, e2.Vertexes[0].Point):
self.assertCoincide(e1.Vertexes[-1].Point, e2.Vertexes[-1].Point)
else:
self.assertCoincide(e1.Vertexes[0].Point, e2.Vertexes[-1].Point)
self.assertCoincide(e1.Vertexes[-1].Point, e2.Vertexes[0].Point)
pm1 = e1.valueAt((e1.FirstParameter + e1.LastParameter)/2)
pm2 = e2.valueAt((e2.FirstParameter + e2.LastParameter)/2)
self.assertCoincide(pm1, pm2)

View File

@@ -145,12 +145,12 @@ class TestPathGeom(PathTestBase):
"""Verify isVertical/isHorizontal for faces"""
# planes
xPlane = Part.makePlane(100, 100, FreeCAD.Vector(), FreeCAD.Vector(1, 0, 0))
yPlane = Part.makePlane(100, 100, FreeCAD.Vector(), FreeCAD.Vector(0, 1, 0))
zPlane = Part.makePlane(100, 100, FreeCAD.Vector(), FreeCAD.Vector(0, 0, 1))
xyPlane = Part.makePlane(100, 100, FreeCAD.Vector(), FreeCAD.Vector(1, 1, 0))
xzPlane = Part.makePlane(100, 100, FreeCAD.Vector(), FreeCAD.Vector(1, 0, 1))
yzPlane = Part.makePlane(100, 100, FreeCAD.Vector(), FreeCAD.Vector(0, 1, 1))
xPlane = Part.makePlane(100, 100, Vector(), Vector(1, 0, 0))
yPlane = Part.makePlane(100, 100, Vector(), Vector(0, 1, 0))
zPlane = Part.makePlane(100, 100, Vector(), Vector(0, 0, 1))
xyPlane = Part.makePlane(100, 100, Vector(), Vector(1, 1, 0))
xzPlane = Part.makePlane(100, 100, Vector(), Vector(1, 0, 1))
yzPlane = Part.makePlane(100, 100, Vector(), Vector(0, 1, 1))
self.assertTrue(PathGeom.isVertical(xPlane))
self.assertTrue(PathGeom.isVertical(yPlane))
@@ -167,12 +167,12 @@ class TestPathGeom(PathTestBase):
self.assertFalse(PathGeom.isHorizontal(yzPlane))
# cylinders
xCylinder = [f for f in Part.makeCylinder(1, 1, FreeCAD.Vector(), FreeCAD.Vector(1, 0, 0)).Faces if type(f.Surface) == Part.Cylinder][0]
yCylinder = [f for f in Part.makeCylinder(1, 1, FreeCAD.Vector(), FreeCAD.Vector(0, 1, 0)).Faces if type(f.Surface) == Part.Cylinder][0]
zCylinder = [f for f in Part.makeCylinder(1, 1, FreeCAD.Vector(), FreeCAD.Vector(0, 0, 1)).Faces if type(f.Surface) == Part.Cylinder][0]
xyCylinder = [f for f in Part.makeCylinder(1, 1, FreeCAD.Vector(), FreeCAD.Vector(1, 1, 0)).Faces if type(f.Surface) == Part.Cylinder][0]
xzCylinder = [f for f in Part.makeCylinder(1, 1, FreeCAD.Vector(), FreeCAD.Vector(1, 0, 1)).Faces if type(f.Surface) == Part.Cylinder][0]
yzCylinder = [f for f in Part.makeCylinder(1, 1, FreeCAD.Vector(), FreeCAD.Vector(0, 1, 1)).Faces if type(f.Surface) == Part.Cylinder][0]
xCylinder = [f for f in Part.makeCylinder(1, 1, Vector(), Vector(1, 0, 0)).Faces if type(f.Surface) == Part.Cylinder][0]
yCylinder = [f for f in Part.makeCylinder(1, 1, Vector(), Vector(0, 1, 0)).Faces if type(f.Surface) == Part.Cylinder][0]
zCylinder = [f for f in Part.makeCylinder(1, 1, Vector(), Vector(0, 0, 1)).Faces if type(f.Surface) == Part.Cylinder][0]
xyCylinder = [f for f in Part.makeCylinder(1, 1, Vector(), Vector(1, 1, 0)).Faces if type(f.Surface) == Part.Cylinder][0]
xzCylinder = [f for f in Part.makeCylinder(1, 1, Vector(), Vector(1, 0, 1)).Faces if type(f.Surface) == Part.Cylinder][0]
yzCylinder = [f for f in Part.makeCylinder(1, 1, Vector(), Vector(0, 1, 1)).Faces if type(f.Surface) == Part.Cylinder][0]
self.assertTrue(PathGeom.isHorizontal(xCylinder))
self.assertTrue(PathGeom.isHorizontal(yCylinder))
@@ -381,3 +381,59 @@ class TestPathGeom(PathTestBase):
pl = e[1].valueAt((e[1].FirstParameter + e[1].LastParameter)/2)
self.assertCurve(e[0], p1, p12, p2)
self.assertCurve(e[1], p2, p23, p3)
def test70(self):
'''Flip a line.'''
edge = Part.Edge(Part.Line(Vector(0,0,0), Vector(3, 2, 1)))
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.Edge(Part.Line(Vector(0,0,0), Vector(-3, -2, -1)))
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
def test71(self):
'''Flip a line segment.'''
edge = Part.Edge(Part.LineSegment(Vector(0,0,0), Vector(3, 2, 1)))
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.Edge(Part.LineSegment(Vector(4,2,1), Vector(-3, -7, 9)))
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeLine(Vector(1,0,3), Vector(3, 2, 1))
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
def test72(self):
'''Flip a circle'''
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, 1))
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, -1))
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
def test73(self):
'''Flip an arc'''
# make sure all 4 quadrants work
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, 1), 45, 90)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, 1), 100, 170)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, 1), 200, 250)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, 1), 300, 340)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
# and the other way around too
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, -1), 45, 90)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, -1), 100, 170)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, -1), 200, 250)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
edge = Part.makeCircle(3, Vector(1, 3, 2), Vector(0, 0, -1), 300, 340)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
def xtest75(self):
'''Flip a b-spline'''
# Disabling for now, there's a bit of a difference
spline = Part.BSplineCurve()
spline.interpolate([Vector(1,2,3), Vector(-3,0,7), Vector(-3,1,9), Vector(1, 3, 5)])
edge = Part.Edge(spline)
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))