From a3ae53a82b386cdd034fdb243f5a9209459abf93 Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Mon, 5 Dec 2016 04:30:49 -0800 Subject: [PATCH] Added arcToHelix. --- .../PathScripts/PathDressupHoldingTags.py | 68 ++++++++++++++++--- src/Mod/Path/PathScripts/PathGeom.py | 25 +++++++ src/Mod/Path/PathTests/TestPathGeom.py | 27 ++++++++ 3 files changed, 111 insertions(+), 9 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py index 60c76861a..34c3d48dd 100644 --- a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py +++ b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py @@ -267,7 +267,20 @@ class Tag: # if we have no core the tip is the origin of the Tag line = Part.Edge(self.tag.centerLine()) debugEdge(line, "------- center line", 'P0') - i = DraftGeomUtils.findIntersection(line, edge, True) + if type(edge.Curve) != Part.Circle and type(edge.Curve) != Part.Line: + p1 = edge.valueAt(edge.FirstParameter) + p2 = edge.valueAt((edge.FirstParameter + edge.LastParameter)/2) + p3 = edge.valueAt(edge.LastParameter) + p1.z = 0 + p2.z = 0 + p3.z = 0 + arc = Part.Edge(Part.Arc(p1, p2, p3)) + aps = DraftGeomUtils.findIntersection(line, arc) + for p in aps: + print("%s - p=%.2f" % (p, arc.Curve.parameter(p))) + i = [edge.valueAt(arc.Curve.parameter(p)) for p in aps] + else: + i = DraftGeomUtils.findIntersection(line, edge) #i = line.Curve.intersect(edge) if i: debugPrint('P0', '------- P0 split @ (%.2f, %.2f, %.2f)' % (i[0].x, i[0].y, i[0].z)) @@ -371,16 +384,53 @@ class Tag: def splitEdgeAt(self, edge, pt): - p = edge.Curve.parameter(pt) + # I'm getting rather tired of this interface, so I decided to implement this myself. + # How hard can it be? + # There are only 3 types of edges passing through here, Line, Circle and Helix ... + if False: + p = edge.Curve.parameter(pt) + #p = edge.parameterAt(Part.Vertex(pt.x, pt.y, pt.z)) - pf = edge.valueAt(edge.FirstParameter) - pl = edge.valueAt(edge.LastParameter) - print("-------- splitAt((%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f): (%.2f, %.2f, %.2f)) -> param[%.2f -> %.2f]: %.2f" % (pf.x, pf.y, pf.z, pl.x, pl.y, pl.z, pt.x, pt.y, pt.z, edge.FirstParameter, edge.LastParameter, p)) + pf = edge.valueAt(edge.FirstParameter) + pl = edge.valueAt(edge.LastParameter) + print("-------- splitAt((%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f): (%.2f, %.2f, %.2f)) -> param[%.2f -> %.2f]: %.2f" % (pf.x, pf.y, pf.z, pl.x, pl.y, pl.z, pt.x, pt.y, pt.z, edge.FirstParameter, edge.LastParameter, p)) - wire = edge.split(p) - # split does not carry the Placement of the original curve foward ... - wire.transformShape(edge.Placement.toMatrix()) - return wire.Edges + print("-------- splitAt(%.2f <= %.2f <= %.2f" % (edge.FirstParameter, p, edge.LastParameter)) + wire = edge.split(p) + # split does not carry the Placement of the original curve foward ... + wire.transformShape(edge.Placement.toMatrix()) + return wire.Edges + p1 = edge.valueAt(edge.FirstParameter) + p2 = pt + p3 = edge.valueAt(edge.LastParameter) + edges = [] + if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment: + edges.append(Part.LineSegment(p1, p2)) + edges.append(Part.LineSegment(p2, p3)) + elif type(edge.Curve) == Part.Circle: + # it's an arc + p = edge.Curve.parameterAt(p2) + p12 = edge.Curve.value((edge.Curve.FirstParameter + p)/2) + p23 = edge.Curve.value((p + edge.Curve.LastParameter)/2) + edges.append(Part.Edge(Part.Arc(p1, p12, p2))) + edges.append(Part.Edge(Part.Arc(p2, p23, p3))) + else: + # it's a helix + # convert to arc + p01 = FreeCAD.Vector(p1.x, p1.y, 0) + p02 = FreeCAD.Vector(p2.x, p2.y, 0) + p03 = FreeCAD.Vector(p3.x, p3.y, 0) + e0 = Part.Edge(Part.Arc(p01, p02, p03)) + # split arc + p0 = e0.Curve.parameterAt(p02) + p012 = e0.Curve.value((e0.Curve.FirstParameter + p0)/2) + p023 = e0.Curve.value((p0 + e0.Curve.LastParameter)/2) + e01 = Part.Edge(Part.Arc(p01, p012, p02)) + e02 = Part.Edge(Part.Arc(p02, p023, p03)) + # transform arcs into helical form + edges.append(self.arcToHelix(e01, p1.z, p2.z)) + edges.append(self.arcToHelix(e02, p2.z, p3.z)) + return edges def mapEdgeToSolid(self, edge, label): pf = edge.valueAt(edge.FirstParameter) diff --git a/src/Mod/Path/PathScripts/PathGeom.py b/src/Mod/Path/PathScripts/PathGeom.py index 2fff4b1e0..7e06829d8 100644 --- a/src/Mod/Path/PathScripts/PathGeom.py +++ b/src/Mod/Path/PathScripts/PathGeom.py @@ -213,3 +213,28 @@ class PathGeom: wires.append(Part.Wire(edges)) return wires + @classmethod + def arcToHelix(cls, edge, z0, z1): + m = FreeCAD.Matrix() + m.unity() + + p1 = edge.valueAt(edge.FirstParameter) + p2 = edge.valueAt(edge.LastParameter) + z = p1.z + + pd = p2 - p1 + dz = z1 - z0 + + #print("arcToHelix(%.2f, %.2f): dz=%.2f, dy=%.2f, z=%.2f" % (z0 ,z1, dz, pd.y, z)) + + m.A32 = dz / pd.y + m.A34 = - m.A32 + if dz < 0: + m.A34 *= p2.y + m.A34 += z1 - z + else: + m.A34 *= p1.y + m.A34 += z0 - z + + e = edge.transformGeometry(m).Edges[0] + return e diff --git a/src/Mod/Path/PathTests/TestPathGeom.py b/src/Mod/Path/PathTests/TestPathGeom.py index 1b72b7edf..779767ccb 100644 --- a/src/Mod/Path/PathTests/TestPathGeom.py +++ b/src/Mod/Path/PathTests/TestPathGeom.py @@ -145,3 +145,30 @@ class TestPathGeom(PathTestBase): self.assertEqual(len(wires[1].Edges), 1) self.assertLine(wires[1].Edges[0], Vector(0,1,0), Vector(0,0,0)) + + def test60(self): + """Verify arcToHelix returns proper helix.""" + p1 = Vector(10,-10,0) + p2 = Vector(0,0,0) + p3 = Vector(10,10,0) + + e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 0, 2) + self.assertCurve(e, p1, p2 + Vector(0,0,1), p3 + Vector(0,0,2)) + + e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 3, 7) + self.assertCurve(e, p1 + Vector(0,0,3), p2 + Vector(0,0,5), p3 + Vector(0,0,7)) + + e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p1, p2, p3)), 9, 1) + self.assertCurve(e, p1 + Vector(0,0,9), p2 + Vector(0,0,5), p3 + Vector(0,0,1)) + + dz = Vector(0,0,3) + p11 = p1 + dz + p12 = p2 + dz + p13 = p3 + dz + + e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p11, p12, p13)), 0, 8) + self.assertCurve(e, p1, p2 + Vector(0,0,4), p3 + Vector(0,0,8)) + + e = PathGeom.arcToHelix(Part.Edge(Part.Arc(p11, p12, p13)), 2, -2) + self.assertCurve(e, p1 + Vector(0,0,2), p2, p3 + Vector(0,0,-2)) +