Straight line intersection with square Tag.
This commit is contained in:
parent
74ac78276b
commit
8ce9c0c305
|
@ -114,12 +114,12 @@ def testSide():
|
|||
testPrintSide(FreeCAD.Vector( 1, 0, 0), FreeCAD.Vector( 0,-1, 0))
|
||||
|
||||
def pathCommandForEdge(edge):
|
||||
pt = edge.valueAt(edge.LastParameter)
|
||||
pt = edge.Curve.EndPoint
|
||||
params = {'X': pt.x, 'Y': pt.y, 'Z': pt.z}
|
||||
if type(edge.Curve) == Part.Line:
|
||||
return Part.Command('G1', params)
|
||||
|
||||
p1 = edge.valueAt(edge.FirstParameter)
|
||||
p1 = edge.Curve.StartPoint
|
||||
p2 = edge.valueAt((edge.FirstParameter + edge.LastParameter)/2)
|
||||
p3 = pt
|
||||
if Side.Left == Side.of(p2 - p1, p3 - p2):
|
||||
|
@ -132,13 +132,25 @@ def pathCommandForEdge(edge):
|
|||
|
||||
|
||||
class Tag:
|
||||
def __init__(self, x, y, width, height, angle, enabled=True):
|
||||
|
||||
@classmethod
|
||||
def FromString(cls, string):
|
||||
try:
|
||||
t = eval(string)
|
||||
return Tag(t[0], t[1], t[2], t[3], t[4], t[5])
|
||||
except:
|
||||
return None
|
||||
|
||||
def __init__(self, x, y, width, height, angle, enabled=True, z=None):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.width = math.fabs(width)
|
||||
self.height = math.fabs(height)
|
||||
self.actualHeight = self.height
|
||||
self.angle = math.fabs(angle)
|
||||
self.enabled = enabled
|
||||
if z is not None:
|
||||
self.createSolidsAt(z)
|
||||
|
||||
def toString(self):
|
||||
return str((self.x, self.y, self.width, self.height, self.angle, self.enabled))
|
||||
|
@ -146,7 +158,14 @@ class Tag:
|
|||
def originAt(self, z):
|
||||
return FreeCAD.Vector(self.x, self.y, z)
|
||||
|
||||
def bottom(self):
|
||||
return self.z
|
||||
|
||||
def top(self):
|
||||
return self.z + self.actualHeight
|
||||
|
||||
def createSolidsAt(self, z):
|
||||
self.z = z
|
||||
r1 = self.width / 2
|
||||
height = self.height
|
||||
if self.angle == 90 and height > 0:
|
||||
|
@ -162,6 +181,7 @@ class Tag:
|
|||
r2 = 0
|
||||
height = r1 * tangens
|
||||
self.core = None
|
||||
self.actualHeight = height
|
||||
self.solid = Part.makeCone(r1, r2, height)
|
||||
else:
|
||||
# degenerated case - no tag
|
||||
|
@ -171,14 +191,144 @@ class Tag:
|
|||
if self.core:
|
||||
self.core.translate(self.originAt(z))
|
||||
|
||||
@classmethod
|
||||
def FromString(cls, string):
|
||||
try:
|
||||
t = eval(string)
|
||||
return Tag(t[0], t[1], t[2], t[3], t[4], t[5])
|
||||
except:
|
||||
return None
|
||||
class Intersection:
|
||||
# An intersection with a tag has 4 markant points, where one might be optional.
|
||||
# P1---P2 P2
|
||||
# / \ /\
|
||||
# / \ / \
|
||||
# / \ / \
|
||||
# ---P0 P3--- ---P0 P3---
|
||||
# If no intersection occured the Intersection can be viewed as being
|
||||
# at P3 with no additional edges.
|
||||
P0 = 2
|
||||
P1 = 3
|
||||
P2 = 4
|
||||
P3 = 5
|
||||
|
||||
def __init__(self, tag):
|
||||
self.tag = tag
|
||||
self.state = self.P3
|
||||
self.edges = []
|
||||
self.tail = None
|
||||
|
||||
def isComplete(self):
|
||||
return self.state == self.P3
|
||||
|
||||
def moveEdgeToPlateau(self, edge):
|
||||
if type(edge.Curve) is Part.Line:
|
||||
pt1 = edge.Curve.StartPoint
|
||||
pt2 = edge.Curve.EndPoint
|
||||
pt1.z = self.tag.top()
|
||||
pt2.z = self.tag.top()
|
||||
#print("\nplateau= %s - %s" %(pt1, pt2))
|
||||
return Part.Edge(Part.Line(pt1, pt2))
|
||||
|
||||
|
||||
def intersect(self, edge):
|
||||
#print("")
|
||||
if self.state == self.P0:
|
||||
#print("----- P0")
|
||||
if self.tag.core:
|
||||
self.state = self.P1
|
||||
i = self.tag.nextIntersectionClosestTo(edge, self.tag.core, edge.Curve.StartPoint)
|
||||
if i:
|
||||
if i == edge.Curve.StartPoint:
|
||||
self.edges.append(Part.Edge(Part.Line(i, FreeCAD.Vector(i.x, i.y, self.tag.top()))))
|
||||
else:
|
||||
e, tail = self.tag.splitEdgeAt(edge, i)
|
||||
self.edges.append(self.mapEdgeTo(e, self.tag.solid))
|
||||
edge = tail
|
||||
else:
|
||||
self.edges.append(self.mapEdgeTo(e, self.tag.solid))
|
||||
# we're done with this edge
|
||||
return self
|
||||
else:
|
||||
p = self.tag.originAt(self.tag.bottom() + self.tag.actualHeight)
|
||||
if DraftGeomUtils.isPtOnEdge(p, edge):
|
||||
e, tail = self.tag.splitEdgeAt(edge, p)
|
||||
self.edges.append(self.mapEdgeTo(e, self.tag.solid))
|
||||
edge = tail
|
||||
self.state = self.P2
|
||||
else:
|
||||
self.edges.append(self.mapEdgeTo(e, self.tag.solid))
|
||||
# we're done with this edge
|
||||
return self
|
||||
|
||||
if self.state == self.P1:
|
||||
#print("----- P1")
|
||||
# must have core, find end of plateau
|
||||
i = self.tag.nextIntersectionClosestTo(edge, self.tag.core, edge.Curve.EndPoint)
|
||||
if i and i != edge.Curve.StartPoint:
|
||||
self.state = self.P2
|
||||
if i == edge.Curve.EndPoint:
|
||||
self.edges.append(self.moveEdgeToPlateau(edge))
|
||||
# edge fully consumed
|
||||
return self
|
||||
else:
|
||||
e, tail = self.tag.splitEdgeAt(edge, i)
|
||||
self.edges.append(self.moveEdgeToPlateau(e))
|
||||
edge = tail
|
||||
else:
|
||||
self.edges.append(self.moveEdgeToPlateau(edge))
|
||||
# edge fully consumed, we're still in P1
|
||||
return self
|
||||
|
||||
if self.state == self.P2:
|
||||
#print("----- P2")
|
||||
i = self.tag.nextIntersectionClosestTo(edge, self.tag.solid, edge.Curve.EndPoint)
|
||||
if i:
|
||||
self.state = self.P3
|
||||
#print("----- P3")
|
||||
if i == edge.Curve.StartPoint:
|
||||
self.edges.append(Part.Edge(Part.Line(FreeCAD.Vector(i.x, i.y, self.tag.top()), i)))
|
||||
self.tail = edge
|
||||
elif i == edge.Curve.EndPoint:
|
||||
self.edges.append(self.mapEdgeTo(edge, self.tag.solid))
|
||||
self.tail = None
|
||||
else:
|
||||
e, tail = self.tag.splitEdgeAt(edge, i)
|
||||
self.edges.append(self.mapEdgeTo(e, self.tag.solid))
|
||||
self.tail = tail
|
||||
|
||||
return self
|
||||
|
||||
|
||||
|
||||
def splitEdgeAt(self, edge, pt):
|
||||
p = edge.Curve.parameter(pt)
|
||||
wire = edge.split(p)
|
||||
return wire.Edges
|
||||
|
||||
|
||||
def nextIntersectionClosestTo(self, edge, solid, refPt):
|
||||
pts = []
|
||||
for face in solid.Faces:
|
||||
i = edge.Curve.intersect(face.Surface)[0]
|
||||
pts.extend([FreeCAD.Vector(p.X, p.Y, p.Z) for p in i])
|
||||
if pts:
|
||||
closest = sorted(pts, key=lambda pt: (pt - refPt).Length)[0]
|
||||
return closest
|
||||
return None
|
||||
|
||||
def intersect(self, edge):
|
||||
inters = self.Intersection(self)
|
||||
if edge.Curve.StartPoint.z < self.top() or edge.Curve.EndPoint.z < self.top():
|
||||
i = self.nextIntersectionClosestTo(edge, self.solid, edge.Curve.StartPoint)
|
||||
if i:
|
||||
inters.state = self.Intersection.P0
|
||||
if i == edge.Curve.EndPoint:
|
||||
inters.edges.append(edge)
|
||||
return inters
|
||||
if i == edge.Curve.StartPoint:
|
||||
tail = edge
|
||||
else:
|
||||
e,tail = self.splitEdgeAt(edge, i)
|
||||
inters.edges.append(e)
|
||||
return inters.intersect(tail)
|
||||
# if we get here there is no intersection with the tag
|
||||
inters.state = self.Intersection.P3
|
||||
inters.tail = edge
|
||||
return inters
|
||||
|
||||
class PathData:
|
||||
def __init__(self, obj):
|
||||
|
@ -235,16 +385,16 @@ class PathData:
|
|||
|
||||
def sortedBase(self, base):
|
||||
# first find the exit point, where base wire is closed
|
||||
edges = [e for e in self.edges if e.valueAt(e.FirstParameter).z == self.minZ and e.valueAt(e.LastParameter).z != self.maxZ]
|
||||
exit = sorted(edges, key=lambda e: -e.valueAt(e.LastParameter).z)[0]
|
||||
pt = exit.valueAt(exit.FirstParameter)
|
||||
edges = [e for e in self.edges if e.Curve.StartPoint.z == self.minZ and e.Curve.EndPoint.z != self.maxZ]
|
||||
exit = sorted(edges, key=lambda e: -e.Curve.EndPoint.z)[0]
|
||||
pt = exit.Curve.StartPoint
|
||||
# then find the first base edge, and sort them until done
|
||||
ordered = []
|
||||
while base:
|
||||
edge = [e for e in base if e.valueAt(e.FirstParameter) == pt][0]
|
||||
edge = [e for e in base if e.Curve.StartPoint == pt][0]
|
||||
ordered.append(edge)
|
||||
base.remove(edge)
|
||||
pt = edge.valueAt(edge.LastParameter)
|
||||
pt = edge.Curve.EndPoint
|
||||
return ordered
|
||||
|
||||
|
||||
|
@ -364,7 +514,7 @@ class PathData:
|
|||
ordered = []
|
||||
for edge in self.base.Edges:
|
||||
ts = [t for t in tags if DraftGeomUtils.isPtOnEdge(t.originAt(self.minZ), edge)]
|
||||
for t in sorted(ts, key=lambda t: (t.originAt(self.minZ) - edge.valueAt(edge.FirstParameter)).Length):
|
||||
for t in sorted(ts, key=lambda t: (t.originAt(self.minZ) - edge.Curve.StartPoint).Length):
|
||||
tags.remove(t)
|
||||
ordered.append(t)
|
||||
if tags:
|
||||
|
@ -392,7 +542,7 @@ class ObjectDressup:
|
|||
|
||||
|
||||
def tagIntersection(self, face, edge):
|
||||
p1 = edge.valueAt(edge.FirstParameter)
|
||||
p1 = edge.Curve.StartPoint
|
||||
pts = edge.Curve.intersect(face.Surface)
|
||||
if pts[0]:
|
||||
closest = sorted(pts[0], key=lambda pt: (pt - p1).Length)[0]
|
||||
|
@ -409,9 +559,9 @@ class ObjectDressup:
|
|||
for face in solid.Faces:
|
||||
pt = self.tagIntersection(face, edge)
|
||||
if pt:
|
||||
if pt == edge.valueAt(edge.FirstParameter):
|
||||
if pt == edge.Curve.StartPoint:
|
||||
pt
|
||||
elif pt != edge.valueAt(edge.LastParameter):
|
||||
elif pt != edge.Curve.EndPoint:
|
||||
parameter = edge.Curve.parameter(pt)
|
||||
wire = edge.split(parameter)
|
||||
commands.append(pathCommandForEdge(wire.Edges[0]))
|
||||
|
|
|
@ -44,61 +44,8 @@ def pointsCoincide(pt1, pt2):
|
|||
return False
|
||||
return True
|
||||
|
||||
class PathDressupHoldingTagsTestCases(unittest.TestCase):
|
||||
"""Unit tests for the HoldingTags dressup."""
|
||||
|
||||
def testTagBasics(self):
|
||||
"""Check Tag origin, serialization and de-serialization."""
|
||||
tag = Tag(77, 13, 4, 5, 90, True)
|
||||
self.assertCoincide(tag.originAt(3), Vector(77, 13, 3))
|
||||
s = tag.toString()
|
||||
tagCopy = Tag.FromString(s)
|
||||
self.assertEqual(tag.x, tagCopy.x)
|
||||
self.assertEqual(tag.y, tagCopy.y)
|
||||
self.assertEqual(tag.height, tagCopy.height)
|
||||
self.assertEqual(tag.width, tagCopy.width)
|
||||
self.assertEqual(tag.enabled, tagCopy.enabled)
|
||||
|
||||
|
||||
def testTagSolidBasic(self):
|
||||
"""For a 90 degree tag the core and solid are both defined and identical cylinders."""
|
||||
tag = Tag(100, 200, 4, 5, 90, True)
|
||||
tag.createSolidsAt(17)
|
||||
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertCylinderAt(tag.solid, Vector(100, 200, 17), 2, 5)
|
||||
|
||||
self.assertIsNotNone(tag.core)
|
||||
self.assertCylinderAt(tag.core, Vector(100, 200, 17), 2, 5)
|
||||
|
||||
def testTagSolidFlatCone(self):
|
||||
"""Tests a Tag that has an angle leaving a flat face on top of the cone."""
|
||||
tag = Tag(0, 0, 18, 5, 45, True)
|
||||
tag.createSolidsAt(0)
|
||||
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertConeAt(tag.solid, Vector(0,0,0), 9, 4, 5)
|
||||
|
||||
self.assertIsNotNone(tag.core)
|
||||
self.assertCylinderAt(tag.core, Vector(0,0,0), 4, 5)
|
||||
|
||||
def testTagSolidCone(self):
|
||||
"""Tests a Tag who's angled sides coincide at the tag's height."""
|
||||
tag = Tag(0, 0, 10, 5, 45, True)
|
||||
tag.createSolidsAt(0)
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertConeAt(tag.solid, Vector(0,0,0), 5, 0, 5)
|
||||
|
||||
self.assertIsNone(tag.core)
|
||||
|
||||
def testTagSolidShortCone(self):
|
||||
"""Tests a Tag that's not wide enough to reach full height."""
|
||||
tag = Tag(0, 0, 5, 17, 60, True)
|
||||
tag.createSolidsAt(0)
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertConeAt(tag.solid, Vector(0,0,0), 2.5, 0, 2.5 * math.tan((60/180.0)*math.pi))
|
||||
|
||||
self.assertIsNone(tag.core)
|
||||
class TagTestCaseBase(unittest.TestCase):
|
||||
"""Base class for all tag test cases providing additional assert functions."""
|
||||
|
||||
def assertCylinderAt(self, solid, pt, r, h):
|
||||
"""Verify that solid is a cylinder at the specified location."""
|
||||
|
@ -127,14 +74,14 @@ class PathDressupHoldingTagsTestCases(unittest.TestCase):
|
|||
def assertCircle(self, edge, pt, r):
|
||||
"""Verivy that edge is a circle at given location."""
|
||||
curve = edge.Curve
|
||||
self.assertTrue(type(curve), Part.Circle)
|
||||
self.assertIs(type(curve), Part.Circle)
|
||||
self.assertCoincide(curve.Center, Vector(pt.x, pt.y, pt.z))
|
||||
self.assertAbout(curve.Radius, r)
|
||||
|
||||
def assertLine(self, edge, pt1, pt2):
|
||||
"""Verify that edge is a line from pt1 to pt2."""
|
||||
curve = edge.Curve
|
||||
self.assertTrue(type(curve), Part.Line)
|
||||
self.assertIs(type(curve), Part.Line)
|
||||
self.assertCoincide(curve.StartPoint, pt1)
|
||||
self.assertCoincide(curve.EndPoint, pt2)
|
||||
|
||||
|
@ -147,4 +94,254 @@ class PathDressupHoldingTagsTestCases(unittest.TestCase):
|
|||
def assertAbout(self, v1, v2):
|
||||
"""Verify that 2 values are the same (accounting for float imprecision)."""
|
||||
#print("assertAbout(%f, %f)" % (v1, v2))
|
||||
self.assertTrue(math.fabs(v1 - v2) < slack)
|
||||
if math.fabs(v1 - v2) > slack:
|
||||
self.fail("%f != %f" % (v1, v2))
|
||||
|
||||
def assertTrapezoid(self, edgs, tail, spec):
|
||||
"""Check that there are 5 edges forming a trapezoid."""
|
||||
edges = list(edgs)
|
||||
if tail:
|
||||
edges.append(tail)
|
||||
self.assertEqual(len(edges), 5)
|
||||
|
||||
p0 = spec[0]
|
||||
p1 = Vector(spec[1], p0.y, p0.z)
|
||||
p2 = Vector(p1.x, p1.y, spec[2])
|
||||
p3 = Vector(-p2.x, p2.y, p2.z)
|
||||
p4 = Vector(p3.x, p3.y, p0.z)
|
||||
p5 = spec[3]
|
||||
|
||||
self.assertLine(edges[0], p0, p1)
|
||||
self.assertLine(edges[1], p1, p2)
|
||||
self.assertLine(edges[2], p2, p3)
|
||||
self.assertLine(edges[3], p3, p4)
|
||||
self.assertLine(edges[4], p4, p5)
|
||||
|
||||
|
||||
class TagTestCases(TagTestCaseBase): # =============
|
||||
"""Unit tests for the HoldingTags dressup."""
|
||||
|
||||
def testTagBasics(self):
|
||||
#"""Check Tag origin, serialization and de-serialization."""
|
||||
tag = Tag(77, 13, 4, 5, 90, True)
|
||||
self.assertCoincide(tag.originAt(3), Vector(77, 13, 3))
|
||||
s = tag.toString()
|
||||
tagCopy = Tag.FromString(s)
|
||||
self.assertEqual(tag.x, tagCopy.x)
|
||||
self.assertEqual(tag.y, tagCopy.y)
|
||||
self.assertEqual(tag.height, tagCopy.height)
|
||||
self.assertEqual(tag.width, tagCopy.width)
|
||||
self.assertEqual(tag.enabled, tagCopy.enabled)
|
||||
|
||||
|
||||
def testTagSolidBasic(self):
|
||||
#"""For a 90 degree tag the core and solid are both defined and identical cylinders."""
|
||||
tag = Tag(100, 200, 4, 5, 90, True)
|
||||
tag.createSolidsAt(17)
|
||||
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertCylinderAt(tag.solid, Vector(100, 200, 17), 2, 5)
|
||||
|
||||
self.assertIsNotNone(tag.core)
|
||||
self.assertCylinderAt(tag.core, Vector(100, 200, 17), 2, 5)
|
||||
|
||||
def testTagSolidFlatCone(self):
|
||||
#"""Tests a Tag that has an angle leaving a flat face on top of the cone."""
|
||||
tag = Tag(0, 0, 18, 5, 45, True)
|
||||
tag.createSolidsAt(0)
|
||||
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertConeAt(tag.solid, Vector(0,0,0), 9, 4, 5)
|
||||
|
||||
self.assertIsNotNone(tag.core)
|
||||
self.assertCylinderAt(tag.core, Vector(0,0,0), 4, 5)
|
||||
|
||||
def testTagSolidCone(self):
|
||||
#"""Tests a Tag who's angled sides coincide at the tag's height."""
|
||||
tag = Tag(0, 0, 10, 5, 45, True)
|
||||
tag.createSolidsAt(0)
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertConeAt(tag.solid, Vector(0,0,0), 5, 0, 5)
|
||||
|
||||
self.assertIsNone(tag.core)
|
||||
|
||||
def testTagSolidShortCone(self):
|
||||
#"""Tests a Tag that's not wide enough to reach full height."""
|
||||
tag = Tag(0, 0, 5, 17, 60, True)
|
||||
tag.createSolidsAt(0)
|
||||
self.assertIsNotNone(tag.solid)
|
||||
self.assertConeAt(tag.solid, Vector(0,0,0), 2.5, 0, 2.5 * math.tan((60/180.0)*math.pi))
|
||||
|
||||
self.assertIsNone(tag.core)
|
||||
|
||||
class SquareTagTestCases(TagTestCaseBase): # =============
|
||||
"""Unit tests for square tags."""
|
||||
|
||||
def testTagNoIntersect(self):
|
||||
#"""Check that the returned tail if no intersection occurs matches the input."""
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
pt1 = Vector(+5, 3, 0)
|
||||
pt2 = Vector(-5, 3, 0)
|
||||
edge = Part.Edge(Part.Line(pt1, pt2))
|
||||
|
||||
i = tag.intersect(edge)
|
||||
self.assertIsNotNone(i)
|
||||
self.assertTrue(i.isComplete())
|
||||
self.assertIsNotNone(i.edges)
|
||||
self.assertFalse(i.edges)
|
||||
self.assertLine(i.tail, pt1, pt2)
|
||||
|
||||
def testTagIntersectLine(self):
|
||||
#"""Test that a straight line passing through a cylindrical tag is split up into 5 segments."""
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
pt1 = Vector(+5, 0, 0)
|
||||
pt2 = Vector(-5, 0, 0)
|
||||
edge = Part.Edge(Part.Line(pt1, pt2))
|
||||
|
||||
i = tag.intersect(edge)
|
||||
self.assertIsNotNone(i)
|
||||
self.assertTrue(i.isComplete())
|
||||
|
||||
pt0a = Vector(+2, 0, 0)
|
||||
pt0b = Vector(+2, 0, 7)
|
||||
pt0c = Vector(-2, 0, 7)
|
||||
pt0d = Vector(-2, 0, 0)
|
||||
|
||||
self.assertEqual(len(i.edges), 4)
|
||||
self.assertLine(i.edges[0], pt1, pt0a)
|
||||
self.assertLine(i.edges[1], pt0a, pt0b)
|
||||
self.assertLine(i.edges[2], pt0b, pt0c)
|
||||
self.assertLine(i.edges[3], pt0c, pt0d)
|
||||
self.assertLine(i.tail, pt0d, pt2)
|
||||
|
||||
|
||||
def testTagIntersectPartialLineP0(self):
|
||||
#"""Make sure line is accounted for if it reaches P0."""
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
edge = Part.Edge(Part.Line(Vector(5, 0, 0), Vector(2, 0, 0)))
|
||||
|
||||
i = tag.intersect(edge)
|
||||
self.assertFalse(i.isComplete())
|
||||
|
||||
self.assertEqual(len(i.edges), 1)
|
||||
self.assertLine(i.edges[0], edge.Curve.StartPoint, edge.Curve.EndPoint)
|
||||
self.assertIsNone(i.tail)
|
||||
|
||||
|
||||
def testTagIntersectPartialLineP1(self):
|
||||
#"""Make sure line is accounted for if it reaches beyond P1."""
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
edge = Part.Edge(Part.Line(Vector(5, 0, 0), Vector(1, 0, 0)))
|
||||
|
||||
i = tag.intersect(edge)
|
||||
self.assertFalse(i.isComplete())
|
||||
|
||||
pt0a = Vector(+2, 0, 0)
|
||||
pt0b = Vector(+2, 0, 7)
|
||||
pt1a = Vector(+1, 0, 7)
|
||||
|
||||
self.assertEqual(len(i.edges), 3)
|
||||
self.assertLine(i.edges[0], edge.Curve.StartPoint, pt0a)
|
||||
self.assertLine(i.edges[1], pt0a, pt0b)
|
||||
self.assertLine(i.edges[2], pt0b, pt1a)
|
||||
self.assertIsNone(i.tail)
|
||||
|
||||
|
||||
def testTagIntersectPartialLineP2(self):
|
||||
#"""Make sure line is accounted for if it reaches beyond P2."""
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
edge = Part.Edge(Part.Line(Vector(5, 0, 0), Vector(-1, 0, 0)))
|
||||
|
||||
i = tag.intersect(edge)
|
||||
self.assertFalse(i.isComplete())
|
||||
|
||||
pt0a = Vector(+2, 0, 0)
|
||||
pt0b = Vector(+2, 0, 7)
|
||||
pt1a = Vector(-1, 0, 7)
|
||||
|
||||
self.assertEqual(len(i.edges), 3)
|
||||
self.assertLine(i.edges[0], edge.Curve.StartPoint, pt0a)
|
||||
self.assertLine(i.edges[1], pt0a, pt0b)
|
||||
self.assertLine(i.edges[2], pt0b, pt1a)
|
||||
self.assertIsNone(i.tail)
|
||||
|
||||
def testTagIntersectPartialLineP11(self):
|
||||
#"""Make sure a line is accounted for if it lies entirely between P1 and P2."""
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
e1 = Part.Edge(Part.Line(Vector(5, 0, 0), Vector(+1, 0, 0)))
|
||||
|
||||
i = tag.intersect(e1)
|
||||
self.assertFalse(i.isComplete())
|
||||
|
||||
e2 = Part.Edge(Part.Line(e1.Curve.EndPoint, Vector(0,0,0)))
|
||||
i = i.intersect(e2)
|
||||
|
||||
pt0a = Vector(+2, 0, 0)
|
||||
pt0b = Vector(+2, 0, 7)
|
||||
pt1a = Vector(+1, 0, 7)
|
||||
pt1b = Vector( 0, 0, 7)
|
||||
|
||||
self.assertEqual(len(i.edges), 4)
|
||||
self.assertLine(i.edges[0], e1.Curve.StartPoint, pt0a)
|
||||
self.assertLine(i.edges[1], pt0a, pt0b)
|
||||
self.assertLine(i.edges[2], pt0b, pt1a)
|
||||
self.assertLine(i.edges[3], pt1a, pt1b)
|
||||
self.assertIsNone(i.tail)
|
||||
|
||||
def testTagIntersectPartialLinesP11223(self):
|
||||
#"""Verify all lines between P0 and P3 are added."""
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
e0 = Part.Edge(Part.Line(Vector(5, 0, 0), Vector(+2, 0, 0)))
|
||||
e1 = Part.Edge(Part.Line(e0.Curve.EndPoint, Vector(+1, 0, 0)))
|
||||
e2 = Part.Edge(Part.Line(e1.Curve.EndPoint, Vector(+0.5, 0, 0)))
|
||||
e3 = Part.Edge(Part.Line(e2.Curve.EndPoint, Vector(-0.5, 0, 0)))
|
||||
e4 = Part.Edge(Part.Line(e3.Curve.EndPoint, Vector(-1, 0, 0)))
|
||||
e5 = Part.Edge(Part.Line(e4.Curve.EndPoint, Vector(-2, 0, 0)))
|
||||
e6 = Part.Edge(Part.Line(e5.Curve.EndPoint, Vector(-5, 0, 0)))
|
||||
|
||||
i = tag
|
||||
for e in [e0, e1, e2, e3, e4, e5]:
|
||||
i = i.intersect(e)
|
||||
self.assertFalse(i.isComplete())
|
||||
i = i.intersect(e6)
|
||||
self.assertTrue(i.isComplete())
|
||||
|
||||
pt0 = Vector(2, 0, 0)
|
||||
pt1 = Vector(2, 0, 7)
|
||||
pt2 = Vector(1, 0, 7)
|
||||
pt3 = Vector(0.5, 0, 7)
|
||||
pt4 = Vector(-0.5, 0, 7)
|
||||
pt5 = Vector(-1, 0, 7)
|
||||
pt6 = Vector(-2, 0, 7)
|
||||
|
||||
self.assertEqual(len(i.edges), 8)
|
||||
|
||||
self.assertLine(i.edges[0], e0.Curve.StartPoint, pt0)
|
||||
self.assertLine(i.edges[1], pt0, pt1)
|
||||
self.assertLine(i.edges[2], pt1, pt2)
|
||||
self.assertLine(i.edges[3], pt2, pt3)
|
||||
self.assertLine(i.edges[4], pt3, pt4)
|
||||
self.assertLine(i.edges[5], pt4, pt5)
|
||||
self.assertLine(i.edges[6], pt5, pt6)
|
||||
self.assertLine(i.edges[7], pt6, e5.Curve.EndPoint)
|
||||
self.assertTrue(i.isComplete())
|
||||
|
||||
self.assertIsNotNone(i.tail)
|
||||
self.assertLine(i.tail, e6.Curve.StartPoint, e6.Curve.EndPoint)
|
||||
|
||||
def testTagIntersectLineAt(self):
|
||||
tag = Tag( 0, 0, 4, 7, 90, True, 0)
|
||||
# for all lines below 7 we get the trapezoid
|
||||
for i in range(0, 7):
|
||||
edge = Part.Edge(Part.Line(Vector(5, 0, i), Vector(-5, 0, i)))
|
||||
s = tag.intersect(edge)
|
||||
self.assertTrue(s.isComplete())
|
||||
self.assertTrapezoid(s.edges, s.tail, [edge.Curve.StartPoint, 2, 7, edge.Curve.EndPoint])
|
||||
|
||||
# for all edges at height or above the original line is used
|
||||
for i in range(7, 9):
|
||||
edge = Part.Edge(Part.Line(Vector(5, 0, i), Vector(-5, 0, i)))
|
||||
s = tag.intersect(edge)
|
||||
self.assertTrue(s.isComplete())
|
||||
self.assertLine(s.tail, edge.Curve.StartPoint, edge.Curve.EndPoint)
|
||||
|
||||
|
|
|
@ -25,4 +25,5 @@
|
|||
import TestApp
|
||||
|
||||
from PathTests.TestPathPost import PathPostTestCases
|
||||
from PathTests.TestPathDressupHoldingTags import PathDressupHoldingTagsTestCases
|
||||
from PathTests.TestPathDressupHoldingTags import TagTestCases
|
||||
from PathTests.TestPathDressupHoldingTags import SquareTagTestCases
|
||||
|
|
Loading…
Reference in New Issue
Block a user