Smooth path with fillets.
This commit is contained in:
parent
0ba1030163
commit
23713a2c51
|
@ -1,7 +1,7 @@
|
|||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2009, 2010 *
|
||||
#* Yorik van Havre <yorik@uncreated.net>, Ken Cline <cline@frii.com> *
|
||||
#* Yorik van Havre <yorik@uncreated.net>, Ken Cline <cline@frii.com> *
|
||||
#* *
|
||||
#* This program is free software; you can redistribute it and/or modify *
|
||||
#* it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
|
@ -133,7 +133,7 @@ def isAligned(edge,axis="x"):
|
|||
if edge.StartPoint.z == edge.EndPoint.z:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getQuad(face):
|
||||
"""getQuad(face): returns a list of 3 vectors (basepoint, Xdir, Ydir) if the face
|
||||
is a quad, or None if not."""
|
||||
|
@ -162,7 +162,7 @@ def areColinear(e1,e2):
|
|||
return False
|
||||
v1 = vec(e1)
|
||||
v2 = vec(e2)
|
||||
a = round(v1.getAngle(v2),precision())
|
||||
a = round(v1.getAngle(v2),precision())
|
||||
if (a == 0) or (a == round(math.pi,precision())):
|
||||
v3 = e2.Vertexes[0].Point.sub(e1.Vertexes[0].Point)
|
||||
if DraftVecUtils.isNull(v3):
|
||||
|
@ -225,7 +225,7 @@ def findEdge(anEdge,aList):
|
|||
if DraftVecUtils.equals(anEdge.Vertexes[-1].Point,aList[e].Vertexes[-1].Point):
|
||||
return(e)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=False,dts=True) :
|
||||
'''findIntersection(edge1,edge2,infinite1=False,infinite2=False,dts=True):
|
||||
|
@ -268,13 +268,13 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
(pt3.x-pt1.x)*(vec2.y-vec2.z))/(norm3.x+norm3.y+norm3.z)
|
||||
vec1.scale(k,k,k)
|
||||
intp = pt1.add(vec1)
|
||||
|
||||
|
||||
if infinite1 == False and not isPtOnEdge(intp,edge1) :
|
||||
return []
|
||||
|
||||
|
||||
if infinite2 == False and not isPtOnEdge(intp,edge2) :
|
||||
return []
|
||||
|
||||
|
||||
return [intp]
|
||||
else :
|
||||
return [] # Lines have same direction
|
||||
|
@ -303,26 +303,26 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
infinite2 = ex2
|
||||
return getLineIntersections(pt1,pt2,pt3,pt4,infinite1,infinite2)
|
||||
|
||||
elif (geomType(edge1) == "Line") and (geomType(edge2) == "Line") :
|
||||
# we have 2 straight lines
|
||||
elif (geomType(edge1) == "Line") and (geomType(edge2) == "Line") :
|
||||
# we have 2 straight lines
|
||||
pt1, pt2, pt3, pt4 = [edge1.Vertexes[0].Point,
|
||||
edge1.Vertexes[1].Point,
|
||||
edge2.Vertexes[0].Point,
|
||||
edge2.Vertexes[1].Point]
|
||||
return getLineIntersections(pt1,pt2,pt3,pt4,infinite1,infinite2)
|
||||
|
||||
|
||||
elif (geomType(edge1) == "Circle") and (geomType(edge2) == "Line") \
|
||||
or (geomType(edge1) == "Line") and (geomType(edge2) == "Circle") :
|
||||
|
||||
|
||||
# deals with an arc or circle and a line
|
||||
|
||||
|
||||
edges = [edge1,edge2]
|
||||
for edge in edges :
|
||||
if geomType(edge) == "Line":
|
||||
line = edge
|
||||
else :
|
||||
arc = edge
|
||||
|
||||
|
||||
dirVec = vec(line) ; dirVec.normalize()
|
||||
pt1 = line.Vertexes[0].Point
|
||||
pt2 = line.Vertexes[1].Point
|
||||
|
@ -335,15 +335,15 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
return [pt1]
|
||||
elif (pt2 in [pt3,pt4]):
|
||||
return [pt2]
|
||||
|
||||
|
||||
if DraftVecUtils.isNull(pt1.sub(center).cross(pt2.sub(center)).cross(arc.Curve.Axis)) :
|
||||
# Line and Arc are on same plane
|
||||
|
||||
|
||||
dOnLine = center.sub(pt1).dot(dirVec)
|
||||
onLine = Vector(dirVec)
|
||||
onLine.scale(dOnLine,dOnLine,dOnLine)
|
||||
toLine = pt1.sub(center).add(onLine)
|
||||
|
||||
|
||||
if toLine.Length < arc.Curve.Radius :
|
||||
dOnLine = (arc.Curve.Radius**2 - toLine.Length**2)**(0.5)
|
||||
onLine = Vector(dirVec)
|
||||
|
@ -356,8 +356,8 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
int = [center.add(toLine)]
|
||||
else :
|
||||
return []
|
||||
|
||||
else :
|
||||
|
||||
else :
|
||||
# Line isn't on Arc's plane
|
||||
if dirVec.dot(arc.Curve.Axis) != 0 :
|
||||
toPlane = Vector(arc.Curve.Axis) ; toPlane.normalize()
|
||||
|
@ -374,7 +374,7 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
return []
|
||||
else :
|
||||
return []
|
||||
|
||||
|
||||
if infinite1 == False :
|
||||
for i in range(len(int)-1,-1,-1) :
|
||||
if not isPtOnEdge(int[i],edge1) :
|
||||
|
@ -384,16 +384,16 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
if not isPtOnEdge(int[i],edge2) :
|
||||
del int[i]
|
||||
return int
|
||||
|
||||
|
||||
elif (geomType(edge1) == "Circle") and (geomType(edge2) == "Circle") :
|
||||
|
||||
|
||||
# deals with 2 arcs or circles
|
||||
|
||||
cent1, cent2 = edge1.Curve.Center, edge2.Curve.Center
|
||||
rad1 , rad2 = edge1.Curve.Radius, edge2.Curve.Radius
|
||||
axis1, axis2 = edge1.Curve.Axis , edge2.Curve.Axis
|
||||
c2c = cent2.sub(cent1)
|
||||
|
||||
|
||||
if DraftVecUtils.isNull(axis1.cross(axis2)) :
|
||||
if round(c2c.dot(axis1),precision()) == 0 :
|
||||
# circles are on same plane
|
||||
|
@ -432,7 +432,7 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
for pt in intTemp :
|
||||
if round(pt.sub(cent2).Length-rad2,precision()) == 0 :
|
||||
int += [pt]
|
||||
|
||||
|
||||
if infinite1 == False :
|
||||
for i in range(len(int)-1,-1,-1) :
|
||||
if not isPtOnEdge(int[i],edge1) :
|
||||
|
@ -441,12 +441,12 @@ def findIntersection(edge1,edge2,infinite1=False,infinite2=False,ex1=False,ex2=F
|
|||
for i in range(len(int)-1,-1,-1) :
|
||||
if not isPtOnEdge(int[i],edge2) :
|
||||
del int[i]
|
||||
|
||||
|
||||
return int
|
||||
else:
|
||||
# print("DraftGeomUtils: Unsupported curve type: (" + str(edge1.Curve) + ", " + str(edge2.Curve) + ")")
|
||||
return []
|
||||
|
||||
|
||||
def wiresIntersect(wire1,wire2):
|
||||
"wiresIntersect(wire1,wire2): returns True if some of the edges of the wires are intersecting otherwise False"
|
||||
for e1 in wire1.Edges:
|
||||
|
@ -454,7 +454,7 @@ def wiresIntersect(wire1,wire2):
|
|||
if findIntersection(e1,e2,dts=False):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def pocket2d(shape,offset):
|
||||
"""pocket2d(shape,offset): return a list of wires obtained from offsetting the wires from the given shape
|
||||
by the given offset, and intersection if needed."""
|
||||
|
@ -551,7 +551,7 @@ def mirror (point, edge):
|
|||
return refl
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def isClockwise(edge,ref=None):
|
||||
"""Returns True if a circle-based edge has a clockwise direction"""
|
||||
if not geomType(edge) == "Circle":
|
||||
|
@ -572,7 +572,7 @@ def isClockwise(edge,ref=None):
|
|||
if n.z < 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def isSameLine(e1,e2):
|
||||
"""isSameLine(e1,e2): return True if the 2 edges are lines and have the same
|
||||
points"""
|
||||
|
@ -587,7 +587,7 @@ def isSameLine(e1,e2):
|
|||
(DraftVecUtils.equals(e1.Vertexes[0].Point,e2.Vertexes[-1].Point)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def isWideAngle(edge):
|
||||
"""returns True if the given edge is an arc with angle > 180 degrees"""
|
||||
if geomType(edge) != "Circle":
|
||||
|
@ -657,9 +657,9 @@ def isLine(bsp):
|
|||
|
||||
def sortEdges(edges):
|
||||
"Deprecated. Use Part.__sortEdges__ instead"
|
||||
|
||||
|
||||
raise DeprecationWarning("Deprecated. Use Part.__sortEdges__ instead")
|
||||
|
||||
|
||||
# Build a dictionary of edges according to their end points.
|
||||
# Each entry is a set of edges that starts, or ends, at the
|
||||
# given vertex hash.
|
||||
|
@ -685,7 +685,7 @@ def sortEdges(edges):
|
|||
if v not in edict and len(se) == 1:
|
||||
startedge = se
|
||||
break
|
||||
# The above may not find a start vertex; if the start edge is reversed,
|
||||
# The above may not find a start vertex; if the start edge is reversed,
|
||||
# the start vertex will appear in edict (and not sdict).
|
||||
if not startedge:
|
||||
for v, se in edict.items():
|
||||
|
@ -735,9 +735,9 @@ def sortEdges(edges):
|
|||
|
||||
def sortEdgesOld(lEdges, aVertex=None):
|
||||
"Deprecated. Use Part.__sortEdges__ instead"
|
||||
|
||||
|
||||
raise DeprecationWarning("Deprecated. Use Part.__sortEdges__ instead")
|
||||
|
||||
|
||||
#There is no reason to limit this to lines only because every non-closed edge always
|
||||
#has exactly two vertices (wmayer)
|
||||
#for e in lEdges:
|
||||
|
@ -781,7 +781,7 @@ def sortEdgesOld(lEdges, aVertex=None):
|
|||
else:
|
||||
return lEdges
|
||||
|
||||
olEdges = [] # ol stands for ordered list
|
||||
olEdges = [] # ol stands for ordered list
|
||||
if aVertex == None:
|
||||
for i in range(len(lEdges)*2) :
|
||||
if len(lEdges[i/2].Vertexes) > 1:
|
||||
|
@ -791,7 +791,7 @@ def sortEdgesOld(lEdges, aVertex=None):
|
|||
return olEdges
|
||||
# if the wire is closed there is no end so choose 1st Vertex
|
||||
# print("closed wire, starting from ",lEdges[0].Vertexes[0].Point)
|
||||
return sortEdgesOld(lEdges, lEdges[0].Vertexes[0])
|
||||
return sortEdgesOld(lEdges, lEdges[0].Vertexes[0])
|
||||
else :
|
||||
#print("looking ",aVertex.Point)
|
||||
result = lookfor(aVertex,lEdges)
|
||||
|
@ -876,7 +876,7 @@ def findWires(edgeslist):
|
|||
if DraftVecUtils.equals(e1.Vertexes[-1].Point,e2.Vertexes[-1].Point):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
edges = edgeslist[:]
|
||||
wires = []
|
||||
lost = []
|
||||
|
@ -916,7 +916,7 @@ def findWires(edgeslist):
|
|||
else:
|
||||
nwires.append(wi)
|
||||
return nwires
|
||||
|
||||
|
||||
def superWire(edgeslist,closed=False):
|
||||
'''superWire(edges,[closed]): forces a wire between edges that don't necessarily
|
||||
have coincident endpoints. If closed=True, wire will always be closed'''
|
||||
|
@ -1089,7 +1089,7 @@ def getNormal(shape):
|
|||
if FreeCAD.GuiUp:
|
||||
import Draft
|
||||
vdir = Draft.get3DView().getViewDirection()
|
||||
if n.getAngle(vdir) < 0.78:
|
||||
if n.getAngle(vdir) < 0.78:
|
||||
n = n.negative()
|
||||
return n
|
||||
|
||||
|
@ -1193,7 +1193,7 @@ def connect(edges,closed=False):
|
|||
i = findIntersection(curr,prev,True,True)
|
||||
if i:
|
||||
v1 = i[DraftVecUtils.closest(curr.Vertexes[0].Point,i)]
|
||||
else:
|
||||
else:
|
||||
v1 = curr.Vertexes[0].Point
|
||||
else:
|
||||
v1 = curr.Vertexes[0].Point
|
||||
|
@ -1203,7 +1203,7 @@ def connect(edges,closed=False):
|
|||
if i:
|
||||
v2 = i[DraftVecUtils.closest(curr.Vertexes[-1].Point,i)]
|
||||
else:
|
||||
v2 = curr.Vertexes[-1].Point
|
||||
v2 = curr.Vertexes[-1].Point
|
||||
else:
|
||||
v2 = curr.Vertexes[-1].Point
|
||||
if geomType(curr) == "Line":
|
||||
|
@ -1444,7 +1444,7 @@ def cleanFaces(shape):
|
|||
if ee.hashCode() in eset:
|
||||
return i
|
||||
return None
|
||||
|
||||
|
||||
# build lookup table
|
||||
lut = {}
|
||||
for face in faceset:
|
||||
|
@ -1655,7 +1655,7 @@ def fillet(lEdges,r,chamfer=False):
|
|||
Returns a list of sorted edges describing a round corner'''
|
||||
|
||||
def getCurveType(edge,existingCurveType = None):
|
||||
'''Builds or completes a dictionnary containing edges with keys "Arc" and "Line"'''
|
||||
'''Builds or completes a dictionnary containing edges with keys "Arc" and "Line"'''
|
||||
if not existingCurveType :
|
||||
existingCurveType = { 'Line' : [], 'Arc' : [] }
|
||||
if issubclass(type(edge.Curve),Part.Line) :
|
||||
|
@ -1665,51 +1665,51 @@ def fillet(lEdges,r,chamfer=False):
|
|||
else :
|
||||
raise ValueError("Edge's curve must be either Line or Arc")
|
||||
return existingCurveType
|
||||
|
||||
|
||||
rndEdges = lEdges[0:2]
|
||||
rndEdges = Part.__sortEdges__(rndEdges)
|
||||
|
||||
if len(rndEdges) < 2 :
|
||||
return rndEdges
|
||||
|
||||
|
||||
if r <= 0 :
|
||||
print("DraftGeomUtils.fillet : Error : radius is negative.")
|
||||
return rndEdges
|
||||
|
||||
|
||||
curveType = getCurveType(rndEdges[0])
|
||||
curveType = getCurveType(rndEdges[1],curveType)
|
||||
|
||||
|
||||
lVertexes = rndEdges[0].Vertexes + [rndEdges[1].Vertexes[-1]]
|
||||
|
||||
|
||||
if len(curveType['Line']) == 2:
|
||||
|
||||
# Deals with 2-line-edges lists --------------------------------------
|
||||
|
||||
|
||||
# Deals with 2-line-edges lists --------------------------------------
|
||||
|
||||
U1 = lVertexes[0].Point.sub(lVertexes[1].Point) ; U1.normalize()
|
||||
U2 = lVertexes[2].Point.sub(lVertexes[1].Point) ; U2.normalize()
|
||||
alpha = U1.getAngle(U2)
|
||||
|
||||
|
||||
if chamfer:
|
||||
# correcting r value so the size of the chamfer = r
|
||||
beta = math.pi - alpha/2
|
||||
r = (r/2)/math.cos(beta)
|
||||
|
||||
|
||||
if round(alpha,precision()) == 0 or round(alpha - math.pi,precision()) == 0: # Edges have same direction
|
||||
print("DraftGeomUtils.fillet : Warning : edges have same direction. Did nothing")
|
||||
return rndEdges
|
||||
|
||||
dToCenter = r / math.sin(alpha/2.)
|
||||
|
||||
dToCenter = r / math.sin(alpha/2.)
|
||||
dToTangent = (dToCenter**2-r**2)**(0.5)
|
||||
dirVect = Vector(U1) ; dirVect.scale(dToTangent,dToTangent,dToTangent)
|
||||
arcPt1 = lVertexes[1].Point.add(dirVect)
|
||||
|
||||
|
||||
dirVect = U2.add(U1) ; dirVect.normalize()
|
||||
dirVect.scale(dToCenter-r,dToCenter-r,dToCenter-r)
|
||||
arcPt2 = lVertexes[1].Point.add(dirVect)
|
||||
|
||||
|
||||
dirVect = Vector(U2) ; dirVect.scale(dToTangent,dToTangent,dToTangent)
|
||||
arcPt3 = lVertexes[1].Point.add(dirVect)
|
||||
|
||||
|
||||
if (dToTangent>lEdges[0].Length) or (dToTangent>lEdges[1].Length) :
|
||||
print("DraftGeomUtils.fillet : Error : radius value ", r," is too high")
|
||||
return rndEdges
|
||||
|
@ -1717,15 +1717,23 @@ def fillet(lEdges,r,chamfer=False):
|
|||
rndEdges[1] = Part.Edge(Part.Line(arcPt1,arcPt3))
|
||||
else:
|
||||
rndEdges[1] = Part.Edge(Part.Arc(arcPt1,arcPt2,arcPt3))
|
||||
rndEdges[0] = Part.Edge(Part.Line(lVertexes[0].Point,arcPt1))
|
||||
rndEdges += [Part.Edge(Part.Line(arcPt3,lVertexes[2].Point))]
|
||||
|
||||
|
||||
if lVertexes[0].Point == arcPt1:
|
||||
# fillet consumes entire first edge
|
||||
rndEdges.pop(0)
|
||||
else:
|
||||
rndEdges[0] = Part.Edge(Part.Line(lVertexes[0].Point,arcPt1))
|
||||
|
||||
if lVertexes[2].Point != arcPt3:
|
||||
# fillet does not consume entire second edge
|
||||
rndEdges += [Part.Edge(Part.Line(arcPt3,lVertexes[2].Point))]
|
||||
|
||||
return rndEdges
|
||||
|
||||
|
||||
elif len(curveType['Arc']) == 1 :
|
||||
|
||||
|
||||
# Deals with lists containing an arc and a line ----------------------------------
|
||||
|
||||
|
||||
if lEdges[0] in curveType['Arc'] :
|
||||
lineEnd = lVertexes[2] ; arcEnd = lVertexes[0] ; arcFirst = True
|
||||
else :
|
||||
|
@ -1734,23 +1742,23 @@ def fillet(lEdges,r,chamfer=False):
|
|||
arcRadius = curveType['Arc'][0].Curve.Radius
|
||||
arcAxis = curveType['Arc'][0].Curve.Axis
|
||||
arcLength = curveType['Arc'][0].Length
|
||||
|
||||
|
||||
U1 = lineEnd.Point.sub(lVertexes[1].Point) ; U1.normalize()
|
||||
toCenter = arcCenter.sub(lVertexes[1].Point)
|
||||
if arcFirst : # make sure the tangent points towards the arc
|
||||
T = arcAxis.cross(toCenter)
|
||||
else :
|
||||
T = toCenter.cross(arcAxis)
|
||||
|
||||
|
||||
projCenter = toCenter.dot(U1)
|
||||
if round(abs(projCenter),precision()) > 0 :
|
||||
normToLine = U1.cross(T).cross(U1)
|
||||
else :
|
||||
normToLine = Vector(toCenter)
|
||||
normToLine = Vector(toCenter)
|
||||
normToLine.normalize()
|
||||
|
||||
|
||||
dCenterToLine = toCenter.dot(normToLine) - r
|
||||
|
||||
|
||||
if round(projCenter,precision()) > 0 :
|
||||
newRadius = arcRadius - r
|
||||
elif round(projCenter,precision()) < 0 or (round(projCenter,precision()) == 0 and U1.dot(T) > 0):
|
||||
|
@ -1758,65 +1766,65 @@ def fillet(lEdges,r,chamfer=False):
|
|||
else :
|
||||
print("DraftGeomUtils.fillet : Warning : edges are already tangent. Did nothing")
|
||||
return rndEdges
|
||||
|
||||
|
||||
toNewCent = newRadius**2-dCenterToLine**2
|
||||
if toNewCent > 0 :
|
||||
toNewCent = abs(abs(projCenter) - toNewCent**(0.5))
|
||||
else :
|
||||
print("DraftGeomUtils.fillet : Error : radius value ", r," is too high")
|
||||
return rndEdges
|
||||
|
||||
|
||||
U1.scale(toNewCent,toNewCent,toNewCent)
|
||||
normToLine.scale(r,r,r)
|
||||
normToLine.scale(r,r,r)
|
||||
newCent = lVertexes[1].Point.add(U1).add(normToLine)
|
||||
|
||||
|
||||
arcPt1= lVertexes[1].Point.add(U1)
|
||||
arcPt2= lVertexes[1].Point.sub(newCent); arcPt2.normalize()
|
||||
arcPt2.scale(r,r,r) ; arcPt2 = arcPt2.add(newCent)
|
||||
if newRadius == arcRadius - r :
|
||||
arcPt3= newCent.sub(arcCenter)
|
||||
else :
|
||||
arcPt3= arcCenter.sub(newCent)
|
||||
arcPt3= arcCenter.sub(newCent)
|
||||
arcPt3.normalize()
|
||||
arcPt3.scale(r,r,r) ; arcPt3 = arcPt3.add(newCent)
|
||||
arcPt = [arcPt1,arcPt2,arcPt3]
|
||||
|
||||
|
||||
|
||||
|
||||
# Warning : In the following I used a trick for calling the right element
|
||||
# in arcPt or V : arcFirst is a boolean so - not arcFirst is -0 or -1
|
||||
# list[-1] is the last element of a list and list[0] the first
|
||||
# this way I don't have to proceed tests to know the position of the arc
|
||||
|
||||
|
||||
myTrick = not arcFirst
|
||||
|
||||
|
||||
V = [arcPt3]
|
||||
V += [arcEnd.Point]
|
||||
|
||||
|
||||
toCenter.scale(-1,-1,-1)
|
||||
|
||||
|
||||
delLength = arcRadius * V[0].sub(arcCenter).getAngle(toCenter)
|
||||
if delLength > arcLength or toNewCent > curveType['Line'][0].Length:
|
||||
if delLength > arcLength or toNewCent > curveType['Line'][0].Length:
|
||||
print("DraftGeomUtils.fillet : Error : radius value ", r," is too high")
|
||||
return rndEdges
|
||||
|
||||
|
||||
arcAsEdge = arcFrom2Pts(V[-arcFirst],V[-myTrick],arcCenter,arcAxis)
|
||||
|
||||
|
||||
V = [lineEnd.Point,arcPt1]
|
||||
lineAsEdge = Part.Edge(Part.Line(V[-arcFirst],V[myTrick]))
|
||||
|
||||
|
||||
rndEdges[not arcFirst] = arcAsEdge
|
||||
rndEdges[arcFirst] = lineAsEdge
|
||||
if chamfer:
|
||||
rndEdges[1:1] = [Part.Edge(Part.Line(arcPt[- arcFirst],arcPt[- myTrick]))]
|
||||
else:
|
||||
rndEdges[1:1] = [Part.Edge(Part.Arc(arcPt[- arcFirst],arcPt[1],arcPt[- myTrick]))]
|
||||
|
||||
|
||||
return rndEdges
|
||||
|
||||
|
||||
elif len(curveType['Arc']) == 2 :
|
||||
|
||||
|
||||
# Deals with lists of 2 arc-edges --------------------------------------------
|
||||
|
||||
|
||||
arcCenter, arcRadius, arcAxis, arcLength, toCenter, T, newRadius = [], [], [], [], [], [], []
|
||||
for i in range(2) :
|
||||
arcCenter += [curveType['Arc'][i].Curve.Center]
|
||||
|
@ -1828,7 +1836,7 @@ def fillet(lEdges,r,chamfer=False):
|
|||
T += [toCenter[1].cross(arcAxis[1])]
|
||||
CentToCent = toCenter[1].sub(toCenter[0])
|
||||
dCentToCent = CentToCent.Length
|
||||
|
||||
|
||||
sameDirection = (arcAxis[0].dot(arcAxis[1]) > 0)
|
||||
TcrossT = T[0].cross(T[1])
|
||||
if sameDirection :
|
||||
|
@ -1844,7 +1852,7 @@ def fillet(lEdges,r,chamfer=False):
|
|||
else :
|
||||
print("DraftGeomUtils.fillet : Warning : edges are already tangent. Did nothing")
|
||||
return rndEdges
|
||||
elif not sameDirection :
|
||||
elif not sameDirection :
|
||||
if round(TcrossT.dot(arcAxis[0]),precision()) > 0 :
|
||||
newRadius += [arcRadius[0]+r]
|
||||
newRadius += [arcRadius[1]-r]
|
||||
|
@ -1864,16 +1872,16 @@ def fillet(lEdges,r,chamfer=False):
|
|||
else :
|
||||
print("DraftGeomUtils.fillet : Warning : edges are already tangent. Did nothing")
|
||||
return rndEdges
|
||||
|
||||
|
||||
if newRadius[0]+newRadius[1] < dCentToCent or \
|
||||
newRadius[0]-newRadius[1] > dCentToCent or \
|
||||
newRadius[1]-newRadius[0] > dCentToCent :
|
||||
print("DraftGeomUtils.fillet : Error : radius value ", r," is too high")
|
||||
return rndEdges
|
||||
|
||||
|
||||
x = (dCentToCent**2+newRadius[0]**2-newRadius[1]**2)/(2*dCentToCent)
|
||||
y = (newRadius[0]**2-x**2)**(0.5)
|
||||
|
||||
|
||||
CentToCent.normalize() ; toCenter[0].normalize() ; toCenter[1].normalize()
|
||||
if abs(toCenter[0].dot(toCenter[1])) != 1 :
|
||||
normVect = CentToCent.cross(CentToCent.cross(toCenter[0]))
|
||||
|
@ -1895,7 +1903,7 @@ def fillet(lEdges,r,chamfer=False):
|
|||
arcPt2 = newCent.add(toThirdPt)
|
||||
arcPt3 = newCent.add(CentToNewCent[1])
|
||||
arcPt = [arcPt1,arcPt2,arcPt3]
|
||||
|
||||
|
||||
arcAsEdge = []
|
||||
for i in range(2) :
|
||||
toCenter[i].scale(-1,-1,-1)
|
||||
|
@ -1905,21 +1913,21 @@ def fillet(lEdges,r,chamfer=False):
|
|||
return rndEdges
|
||||
V = [arcPt[-i],lVertexes[-i].Point]
|
||||
arcAsEdge += [arcFrom2Pts(V[i-1],V[-i],arcCenter[i],arcAxis[i])]
|
||||
|
||||
|
||||
rndEdges[0] = arcAsEdge[0]
|
||||
rndEdges[1] = arcAsEdge[1]
|
||||
if chamfer:
|
||||
rndEdges[1:1] = [Part.Edge(Part.Line(arcPt[0],arcPt[2]))]
|
||||
else:
|
||||
rndEdges[1:1] = [Part.Edge(Part.Arc(arcPt[0],arcPt[1],arcPt[2]))]
|
||||
|
||||
|
||||
return rndEdges
|
||||
|
||||
|
||||
def filletWire(aWire,r,chamfer=False):
|
||||
''' Fillets each angle of a wire with r as radius value
|
||||
if chamfer is true, a chamfer is made instead and r is the
|
||||
size of the chamfer'''
|
||||
|
||||
|
||||
edges = aWire.Edges
|
||||
edges = Part.__sortEdges__(edges)
|
||||
filEdges = [edges[0]]
|
||||
|
@ -1935,7 +1943,7 @@ def filletWire(aWire,r,chamfer=False):
|
|||
filEdges[-1:] = result[0:2]
|
||||
filEdges[0] = result[2]
|
||||
return Part.Wire(filEdges)
|
||||
|
||||
|
||||
def getCircleFromSpline(edge):
|
||||
"returns a circle-based edge from a bspline-based edge"
|
||||
if geomType(edge) != "BSplineCurve":
|
||||
|
@ -2018,7 +2026,7 @@ def cleanProjection(shape,tessellate=True,seglength=.05):
|
|||
except:
|
||||
print("Debug: error cleaning edge ",e)
|
||||
return Part.makeCompound(newedges)
|
||||
|
||||
|
||||
def curvetosegment(curve,seglen):
|
||||
points = curve.discretize(seglen)
|
||||
p0 = points[0]
|
||||
|
@ -2049,10 +2057,10 @@ def tessellateProjection(shape,seglen):
|
|||
except:
|
||||
print("Debug: error cleaning edge ",e)
|
||||
return Part.makeCompound(newedges)
|
||||
|
||||
|
||||
|
||||
|
||||
def rebaseWire(wire,vidx):
|
||||
|
||||
|
||||
"""rebaseWire(wire,vidx): returns a new wire which is a copy of the
|
||||
current wire, but where the first vertex is the vertex indicated by the given
|
||||
index vidx, starting from 1. 0 will return an exact copy of the wire."""
|
||||
|
@ -2109,7 +2117,7 @@ def getBoundaryAngles(angle,alist):
|
|||
if a < higher:
|
||||
higher = a
|
||||
return (lower,higher)
|
||||
|
||||
|
||||
|
||||
def circleFrom2tan1pt(tan1, tan2, point):
|
||||
"circleFrom2tan1pt(edge, edge, Vector)"
|
||||
|
@ -2237,7 +2245,7 @@ def circleFrom3LineTangents (edge1, edge2, edge3):
|
|||
bis23 = angleBisection(edge2,edge3)
|
||||
bis31 = angleBisection(edge3,edge1)
|
||||
intersections = []
|
||||
int = findIntersection(bis12, bis23, True, True)
|
||||
int = findIntersection(bis12, bis23, True, True)
|
||||
if int:
|
||||
radius = findDistance(int[0],edge1).Length
|
||||
intersections.append(Part.Circle(int[0],NORM,radius))
|
||||
|
@ -2457,7 +2465,7 @@ def innerSoddyCircle(circle1, circle2, circle3):
|
|||
print("debug: innerSoddyCircle bad parameters!\n")
|
||||
# FreeCAD.Console.PrintMessage("debug: innerSoddyCircle bad parameters!\n")
|
||||
return None
|
||||
|
||||
|
||||
def circleFrom3CircleTangents(circle1, circle2, circle3):
|
||||
'''
|
||||
http://en.wikipedia.org/wiki/Problem_of_Apollonius#Inversive_methods
|
||||
|
@ -2560,7 +2568,7 @@ def determinant (mat,n):
|
|||
else:
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
def findHomotheticCenterOfCircles(circle1, circle2):
|
||||
'''
|
||||
findHomotheticCenterOfCircles(circle1, circle2)
|
||||
|
|
|
@ -27,6 +27,8 @@ import Path
|
|||
from PathScripts import PathUtils
|
||||
from PySide import QtCore, QtGui
|
||||
import math
|
||||
import Part
|
||||
import DraftGeomUtils
|
||||
|
||||
"""Dogbone Dressup object and FreeCAD command"""
|
||||
|
||||
|
@ -45,6 +47,20 @@ except AttributeError:
|
|||
movecommands = ['G0', 'G00', 'G1', 'G01', 'G2', 'G02', 'G3', 'G03']
|
||||
movestraight = ['G1', 'G01']
|
||||
|
||||
def debugMarker(vector, label):
|
||||
obj = FreeCAD.ActiveDocument.addObject("Part::Sphere", label)
|
||||
obj.Label = label
|
||||
obj.Radius = 0.5
|
||||
obj.Placement = FreeCAD.Placement(vector, FreeCAD.Rotation(FreeCAD.Vector(0,0,1), 0))
|
||||
|
||||
def debugCircle(vector, r, label):
|
||||
obj = FreeCAD.ActiveDocument.addObject("Part::Cylinder", label)
|
||||
obj.Label = label
|
||||
obj.Radius = r
|
||||
obj.Height = 1
|
||||
obj.Placement = FreeCAD.Placement(vector, FreeCAD.Rotation(FreeCAD.Vector(0,0,1), 0))
|
||||
obj.ViewObject.Transparency = 95
|
||||
|
||||
class Style:
|
||||
Dogbone = 'Dogbone'
|
||||
Tbone_H = 'T-bone horizontal'
|
||||
|
@ -155,6 +171,9 @@ class Chord (object):
|
|||
def g1Command(self):
|
||||
return Path.Command("G1", {"X": self.End.x, "Y": self.End.y})
|
||||
|
||||
def arcCommand(self, orientation):
|
||||
return self.g1Command()
|
||||
|
||||
def isAPlungeMove(self):
|
||||
return self.End.z != self.Start.z
|
||||
|
||||
|
@ -195,7 +214,14 @@ class Chord (object):
|
|||
else:
|
||||
print("Now this really sucks")
|
||||
|
||||
return (x, y)
|
||||
return FreeCAD.Vector(x, y, self.End.z)
|
||||
|
||||
def perpendicular(self):
|
||||
v = self.asVector()
|
||||
return FreeCAD.Vector(-v.y, v.x, 0)
|
||||
|
||||
def footOfPerpendicularFrom(self, vector):
|
||||
return self.intersection(Chord(vector, vector + self.perpendicular()))
|
||||
|
||||
class ObjectDressup:
|
||||
|
||||
|
@ -235,21 +261,11 @@ class ObjectDressup:
|
|||
def shouldInsertDogbone(self, obj, inChord, outChord):
|
||||
return outChord.foldsBackOrTurns(inChord, self.theOtherSideOf(obj.Side))
|
||||
|
||||
# draw circles where dogbones go, easier to spot during testing
|
||||
def debugCircleBone(self, obj,inChord, outChord):
|
||||
di = 0.
|
||||
dj = 0.5
|
||||
if inChord.Start.x < outChord.End.x:
|
||||
dj = -dj
|
||||
circle = Path.Command("G1", {"I": di, "J": dj}).Parameters
|
||||
circle.update({"X": inChord.End.x, "Y": inChord.End.y})
|
||||
return [ Path.Command("G3", circle) ]
|
||||
|
||||
def adaptiveBoneLength(self, obj, inChord, outChord, angle):
|
||||
iChord = inChord.offsetBy(self.toolRadius)
|
||||
oChord = outChord.offsetBy(self.toolRadius)
|
||||
x,y = iChord.intersection(oChord, self.toolRadius)
|
||||
dest = inChord.moveTo(FreeCAD.Vector(x, y, inChord.End.z))
|
||||
v = iChord.intersection(oChord, self.toolRadius)
|
||||
dest = inChord.moveTo(FreeCAD.Vector(v.x, v.y, v.z))
|
||||
destAngle = dest.getAngleXY()
|
||||
distance = dest.getLength() - self.toolRadius * math.fabs(math.cos(destAngle - angle))
|
||||
#print("adapt")
|
||||
|
@ -258,13 +274,43 @@ class ObjectDressup:
|
|||
#print(" = (%.2f, %.2f) -> %.2f (%.2f %.2f) -> %.2f" % (x, y, dest.getLength(), destAngle/math.pi, angle/math.pi, distance))
|
||||
return distance
|
||||
|
||||
def smoothChordCommands(self, inChord, outChord, smooth):
|
||||
def smoothChordCommands(self, inChord, outChord, side, smooth):
|
||||
if smooth == 0:
|
||||
return [ inChord.g1Command(), outChord.g1Command() ]
|
||||
print("(%.2f, %.2f) -> (%.2f, %.2f) -> (%.2f, %.2f)" % (inChord.Start.x, inChord.Start.y, inChord.End.x, inChord.End.y, outChord.End.x, outChord.End.y))
|
||||
inAngle = inChord.getAngleXY()
|
||||
outAngle = outChord.getAngleXY()
|
||||
if inAngle == outAngle: # straight line, combine g1
|
||||
return [ Chord(inChord.Start, outChord.End).g1Command() ]
|
||||
print(" inAngle = %.2f outAngle = %.2f" % (inAngle/math.pi, outAngle/math.pi))
|
||||
if inAngle == outAngle: # straight line, outChord includes inChord
|
||||
print(" ---> (%.2f, %.2f)" %(outChord.End.x, outChord.End.y))
|
||||
return [ outChord.g1Command() ]
|
||||
print("%s :: %s" % (inChord, outChord))
|
||||
inEdge = DraftGeomUtils.edg(inChord.Start, inChord.End)
|
||||
outEdge = DraftGeomUtils.edg(outChord.Start, outChord.End)
|
||||
#wire = Part.Wire([inEdge, outEdge])
|
||||
#print(" => %s" % wire)
|
||||
#wire = wire.makeOffset2D(self.toolRadius)
|
||||
#print(" ==> %s" % wire)
|
||||
#wire = wire.makeOffset2D(-self.toolRadius)
|
||||
#print(" ===> %s" % wire)
|
||||
radius = self.toolRadius
|
||||
while radius > 0:
|
||||
lastpt = None
|
||||
commands = ""
|
||||
edges = DraftGeomUtils.fillet([inEdge, outEdge], radius)
|
||||
if DraftGeomUtils.isSameLine(edges[0], inEdge) or DraftGeomUtils.isSameLine(edges[1], inEdge):
|
||||
print("Oh, we got a problem, try smaller radius")
|
||||
radius = radius - 0.1 * self.toolRadius
|
||||
continue
|
||||
print("we're good")
|
||||
#for edge in wire.Edges[:-1]: # makeOffset2D closes the wire
|
||||
for edge in edges:
|
||||
if not lastpt:
|
||||
lastpt = edge.Vertexes[0].Point
|
||||
lastpt, cmds = PathUtils.edge_to_path(lastpt, edge, 0)
|
||||
commands += cmds
|
||||
path = Path.Path(commands)
|
||||
return path.Commands
|
||||
return [ inChord.g1Command(), outChord.g1Command() ]
|
||||
|
||||
def inOutBoneCommands(self, obj, inChord, outChord, angle, fixedLength, smooth):
|
||||
|
@ -279,9 +325,12 @@ class ObjectDressup:
|
|||
boneInChord = inChord.moveBy(x, y, 0)
|
||||
boneOutChord = boneInChord.moveTo(outChord.Start)
|
||||
|
||||
debugCircle(boneInChord.Start, self.toolRadius, 'boneStart')
|
||||
debugCircle(boneInChord.End, self.toolRadius, 'boneEnd')
|
||||
|
||||
bones = []
|
||||
bones.extend(self.smoothChordCommands(inChord, boneInChord, smooth & Smooth.In))
|
||||
bones.extend(self.smoothChordCommands(boneOutChord, outChord, smooth & Smooth.Out))
|
||||
bones.extend(self.smoothChordCommands(inChord, boneInChord, obj.Side, smooth & Smooth.In))
|
||||
bones.extend(self.smoothChordCommands(boneOutChord, outChord, obj.Side, smooth & Smooth.Out))
|
||||
return bones
|
||||
|
||||
def dogboneAngle(self, obj, inChord, outChord):
|
||||
|
@ -349,12 +398,7 @@ class ObjectDressup:
|
|||
return (blacklisted, parentConsumed)
|
||||
|
||||
# Generate commands necessary to execute the dogbone
|
||||
def boneCommands(self, obj, boneId, inChord, outChord, smooth):
|
||||
loc = (inChord.End.x, inChord.End.y)
|
||||
blacklisted, inaccessible = self.boneIsBlacklisted(obj, boneId, loc)
|
||||
enabled = not blacklisted
|
||||
self.bones.append((boneId, loc, enabled, inaccessible))
|
||||
|
||||
def boneCommands(self, obj, enabled, inChord, outChord, smooth):
|
||||
if enabled:
|
||||
if obj.Style == Style.Dogbone:
|
||||
return self.dogbone(obj, inChord, outChord, smooth)
|
||||
|
@ -366,13 +410,22 @@ class ObjectDressup:
|
|||
return self.tboneLongEdge(obj, inChord, outChord, smooth)
|
||||
if obj.Style == Style.Tbone_S:
|
||||
return self.tboneShortEdge(obj, inChord, outChord, smooth)
|
||||
return self.debugCircleBone(obj, inChord, outChord)
|
||||
else:
|
||||
return []
|
||||
return [ inChord.g1Command(), outChord.g1Command() ]
|
||||
|
||||
def insertBone(self, boneId, obj, inChord, outChord, commands, smooth):
|
||||
bones = self.boneCommands(obj, boneId, inChord, outChord, smooth)
|
||||
print(">----------------------------------- %d --------------------------------------" % boneId)
|
||||
loc = (inChord.End.x, inChord.End.y)
|
||||
blacklisted, inaccessible = self.boneIsBlacklisted(obj, boneId, loc)
|
||||
enabled = not blacklisted
|
||||
self.bones.append((boneId, loc, enabled, inaccessible))
|
||||
|
||||
if boneId < 9:
|
||||
bones = self.boneCommands(obj, enabled, inChord, outChord, smooth)
|
||||
else:
|
||||
bones = self.boneCommands(obj, False, inChord, outChord, smooth)
|
||||
commands.extend(bones[:-1])
|
||||
print("<----------------------------------- %d --------------------------------------" % boneId)
|
||||
return boneId + 1, bones[-1]
|
||||
|
||||
def execute(self, obj):
|
||||
|
@ -424,6 +477,8 @@ class ObjectDressup:
|
|||
commands.append(lastCommand)
|
||||
lastCommand = None
|
||||
commands.append(thisCmd)
|
||||
#for cmd in commands:
|
||||
# print("cmd = '%s'" % cmd)
|
||||
path = Path.Path(commands)
|
||||
obj.Path = path
|
||||
|
||||
|
|
|
@ -233,6 +233,51 @@ def reverseEdge(e):
|
|||
|
||||
return newedge
|
||||
|
||||
def edge_to_path(lastpt, edge, Z, hf=2.0):
|
||||
if isinstance(edge.Curve, Part.Circle):
|
||||
# FreeCAD.Console.PrintMessage("arc\n")
|
||||
arcstartpt = edge.valueAt(edge.FirstParameter)
|
||||
midpt = edge.valueAt(
|
||||
(edge.FirstParameter + edge.LastParameter) * 0.5)
|
||||
arcendpt = edge.valueAt(edge.LastParameter)
|
||||
# arcchkpt = edge.valueAt(edge.LastParameter * .99)
|
||||
|
||||
if DraftVecUtils.equals(lastpt, arcstartpt):
|
||||
startpt = arcstartpt
|
||||
endpt = arcendpt
|
||||
else:
|
||||
startpt = arcendpt
|
||||
endpt = arcstartpt
|
||||
center = edge.Curve.Center
|
||||
relcenter = center.sub(lastpt)
|
||||
# FreeCAD.Console.PrintMessage("arc startpt= " + str(startpt)+ "\n")
|
||||
# FreeCAD.Console.PrintMessage("arc midpt= " + str(midpt)+ "\n")
|
||||
# FreeCAD.Console.PrintMessage("arc endpt= " + str(endpt)+ "\n")
|
||||
arc_cw = check_clockwise(
|
||||
[(startpt.x, startpt.y), (midpt.x, midpt.y), (endpt.x, endpt.y)])
|
||||
# FreeCAD.Console.PrintMessage("arc_cw="+ str(arc_cw)+"\n")
|
||||
if arc_cw:
|
||||
output = "G2"
|
||||
else:
|
||||
output = "G3"
|
||||
output += " X" + str(fmt(endpt.x)) + " Y" + \
|
||||
str(fmt(endpt.y)) + " Z" + str(fmt(Z)) + " F" + str(hf)
|
||||
output += " I" + str(fmt(relcenter.x)) + " J" + \
|
||||
str(fmt(relcenter.y)) + " K" + str(fmt(relcenter.z))
|
||||
output += "\n"
|
||||
lastpt = endpt
|
||||
# FreeCAD.Console.PrintMessage("last pt arc= " + str(lastpt)+ "\n")
|
||||
else:
|
||||
point = edge.Vertexes[-1].Point
|
||||
if DraftVecUtils.equals(point, lastpt): # edges can come flipped
|
||||
point = edge.Vertexes[0].Point
|
||||
output = "G1 X" + str(fmt(point.x)) + " Y" + str(fmt(point.y)) + \
|
||||
" Z" + str(fmt(Z)) + " F" + str(hf) + "\n"
|
||||
lastpt = point
|
||||
# FreeCAD.Console.PrintMessage("line\n")
|
||||
# FreeCAD.Console.PrintMessage("last pt line= " + str(lastpt)+ "\n")
|
||||
return lastpt, output
|
||||
|
||||
|
||||
def convert(toolpath, Z=0.0, PlungeAngle=90.0, Zprevious=None, StopLength=None, vf=1.0, hf=2.0) :
|
||||
'''convert(toolpath,Z=0.0,vf=1.0,hf=2.0,PlungeAngle=90.0,Zprevious=None,StopLength=None) Converts lines and arcs to G1,G2,G3 moves. Returns a string.'''
|
||||
|
@ -248,51 +293,6 @@ def convert(toolpath, Z=0.0, PlungeAngle=90.0, Zprevious=None, StopLength=None,
|
|||
else:
|
||||
Zprevious = Z
|
||||
|
||||
def edge_to_path(lastpt, edge, Z):
|
||||
if isinstance(edge.Curve, Part.Circle):
|
||||
# FreeCAD.Console.PrintMessage("arc\n")
|
||||
arcstartpt = edge.valueAt(edge.FirstParameter)
|
||||
midpt = edge.valueAt(
|
||||
(edge.FirstParameter + edge.LastParameter) * 0.5)
|
||||
arcendpt = edge.valueAt(edge.LastParameter)
|
||||
# arcchkpt = edge.valueAt(edge.LastParameter * .99)
|
||||
|
||||
if DraftVecUtils.equals(lastpt, arcstartpt):
|
||||
startpt = arcstartpt
|
||||
endpt = arcendpt
|
||||
else:
|
||||
startpt = arcendpt
|
||||
endpt = arcstartpt
|
||||
center = edge.Curve.Center
|
||||
relcenter = center.sub(lastpt)
|
||||
# FreeCAD.Console.PrintMessage("arc startpt= " + str(startpt)+ "\n")
|
||||
# FreeCAD.Console.PrintMessage("arc midpt= " + str(midpt)+ "\n")
|
||||
# FreeCAD.Console.PrintMessage("arc endpt= " + str(endpt)+ "\n")
|
||||
arc_cw = check_clockwise(
|
||||
[(startpt.x, startpt.y), (midpt.x, midpt.y), (endpt.x, endpt.y)])
|
||||
# FreeCAD.Console.PrintMessage("arc_cw="+ str(arc_cw)+"\n")
|
||||
if arc_cw:
|
||||
output = "G2"
|
||||
else:
|
||||
output = "G3"
|
||||
output += " X" + str(fmt(endpt.x)) + " Y" + \
|
||||
str(fmt(endpt.y)) + " Z" + str(fmt(Z)) + " F" + str(hf)
|
||||
output += " I" + str(fmt(relcenter.x)) + " J" + \
|
||||
str(fmt(relcenter.y)) + " K" + str(fmt(relcenter.z))
|
||||
output += "\n"
|
||||
lastpt = endpt
|
||||
# FreeCAD.Console.PrintMessage("last pt arc= " + str(lastpt)+ "\n")
|
||||
else:
|
||||
point = edge.Vertexes[-1].Point
|
||||
if DraftVecUtils.equals(point, lastpt): # edges can come flipped
|
||||
point = edge.Vertexes[0].Point
|
||||
output = "G1 X" + str(fmt(point.x)) + " Y" + str(fmt(point.y)) + \
|
||||
" Z" + str(fmt(Z)) + " F" + str(hf) + "\n"
|
||||
lastpt = point
|
||||
# FreeCAD.Console.PrintMessage("line\n")
|
||||
# FreeCAD.Console.PrintMessage("last pt line= " + str(lastpt)+ "\n")
|
||||
return lastpt, output
|
||||
|
||||
lastpt = None
|
||||
output = ""
|
||||
path_length = 0.0
|
||||
|
@ -334,13 +334,13 @@ def convert(toolpath, Z=0.0, PlungeAngle=90.0, Zprevious=None, StopLength=None,
|
|||
subwire = edge.split(t)
|
||||
assert(len(subwire.Edges) == 2)
|
||||
Z_cur = Z
|
||||
lastpt, codes = edge_to_path(lastpt, subwire.Edges[0], Z_cur)
|
||||
lastpt, codes = edge_to_path(lastpt, subwire.Edges[0], Z_cur, hf)
|
||||
output += codes
|
||||
edge = subwire.Edges[1]
|
||||
else:
|
||||
Z_cur = Z_next
|
||||
|
||||
lastpt, codes = edge_to_path(lastpt, edge, Z_cur)
|
||||
lastpt, codes = edge_to_path(lastpt, edge, Z_cur, hf)
|
||||
output += codes
|
||||
|
||||
if StopLength:
|
||||
|
|
Loading…
Reference in New Issue
Block a user