Added support for feeds and speeds to to cmdsForEdge.
This commit is contained in:
committed by
Yorik van Havre
parent
2aee1e8368
commit
bd2beb0bf2
@@ -208,7 +208,30 @@ def xy(point):
|
||||
Convenience function to return the projection of the Vector in the XY-plane."""
|
||||
return Vector(point.x, point.y, 0)
|
||||
|
||||
def cmdsForEdge(edge, flip = False, useHelixForBSpline = True, segm = 50):
|
||||
def speedBetweenPoints(p0, p1, hSpeed, vSpeed):
|
||||
if isRoughly(hSpeed, vSpeed):
|
||||
return hSpeed
|
||||
|
||||
d = p1 - p0
|
||||
if isRoughly(0.0, d.z):
|
||||
return hSpeed
|
||||
if isRoughly(0.0, d.x) and isRoughly(0.0, d.y):
|
||||
return vSpeed
|
||||
# need to interpolate between hSpeed and vSpeed depending on the pitch
|
||||
pitch = 2 * math.atan2(xy(d).Length, math.fabs(d.z)) / math.pi
|
||||
while pitch < 0:
|
||||
pitch = pitch + 1
|
||||
while pitch > 1:
|
||||
pitch = pitch - 1
|
||||
print(" pitch = %g %g (%.2f, %.2f, %.2f) -> %.2f" % (pitch, math.atan2(xy(d).Length, d.z), d.x, d.y, d.z, xy(d).Length))
|
||||
speed = vSpeed + pitch * (hSpeed - vSpeed)
|
||||
if speed > hSpeed and speed > vSpeed:
|
||||
return max(hSpeed, vSpeed)
|
||||
if speed < hSpeed and speed < vSpeed:
|
||||
return min(hSpeed, vSpeed)
|
||||
return speed
|
||||
|
||||
def cmdsForEdge(edge, flip = False, useHelixForBSpline = True, segm = 50, hSpeed = 0, vSpeed = 0):
|
||||
"""(edge, flip=False, useHelixForBSpline=True, segm=50) -> List(Path.Command)
|
||||
Returns a list of Path.Command representing the given edge.
|
||||
If flip is True the edge is considered to be backwards.
|
||||
@@ -220,6 +243,9 @@ def cmdsForEdge(edge, flip = False, useHelixForBSpline = True, segm = 50):
|
||||
pt = edge.valueAt(edge.LastParameter) if not flip else edge.valueAt(edge.FirstParameter)
|
||||
params = {'X': pt.x, 'Y': pt.y, 'Z': pt.z}
|
||||
if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment:
|
||||
if hSpeed > 0 and vSpeed > 0:
|
||||
pt2 = edge.valueAt(edge.FirstParameter) if not flip else edge.valueAt(edge.LastParameter)
|
||||
params.update({'F': speedBetweenPoints(pt, pt2, hSpeed, vSpeed)})
|
||||
commands = [Path.Command('G1', params)]
|
||||
else:
|
||||
p1 = edge.valueAt(edge.FirstParameter) if not flip else edge.valueAt(edge.LastParameter)
|
||||
@@ -251,6 +277,9 @@ def cmdsForEdge(edge, flip = False, useHelixForBSpline = True, segm = 50):
|
||||
PathLog.debug("**** (%.2f, %.2f, %.2f)" % (offset.x, offset.y, offset.z))
|
||||
|
||||
params.update({'I': offset.x, 'J': offset.y, 'K': (p3.z - p1.z)/2})
|
||||
# G2/G3 commands are always performed at hSpeed
|
||||
if hSpeed > 0:
|
||||
params.update({'F': hSpeed})
|
||||
commands = [ Path.Command(cmd, params) ]
|
||||
|
||||
else:
|
||||
@@ -266,14 +295,19 @@ def cmdsForEdge(edge, flip = False, useHelixForBSpline = True, segm = 50):
|
||||
segments = int(math.ceil((deviation / eStraight.Length) * segm))
|
||||
#print("**** pixellation with %d segments" % segments)
|
||||
dParameter = (edge.LastParameter - edge.FirstParameter) / segments
|
||||
# starting point
|
||||
p0 = edge.valueAt(edge.LastParameter) if flip else edge.valueAt(edge.FirstParameter)
|
||||
for i in range(0, segments):
|
||||
if flip:
|
||||
p = edge.valueAt(edge.LastParameter - (i + 1) * dParameter)
|
||||
else:
|
||||
p = edge.valueAt(edge.FirstParameter + (i + 1) * dParameter)
|
||||
if hSpeed > 0 and vSpeed > 0:
|
||||
params.update({'F': speedBetweenPoints(p0, p, hSpeed, vSpeed)})
|
||||
cmd = Path.Command('G1', {'X': p.x, 'Y': p.y, 'Z': p.z})
|
||||
#print("***** %s" % cmd)
|
||||
commands.append(cmd)
|
||||
p0 = p
|
||||
#print commands
|
||||
return commands
|
||||
|
||||
|
||||
@@ -181,12 +181,68 @@ class TestPathGeom(PathTestBase):
|
||||
self.assertFalse(PathGeom.isHorizontal(xzCylinder))
|
||||
self.assertFalse(PathGeom.isHorizontal(yzCylinder))
|
||||
|
||||
def test07(self):
|
||||
"""Verify speed interpolation works for different pitches"""
|
||||
# horizontal
|
||||
self.assertRoughly(100, PathGeom.speedBetweenPoints(Vector(), Vector(1,1,0), 100, 50))
|
||||
self.assertRoughly(100, PathGeom.speedBetweenPoints(Vector(1,1,0), Vector(), 100, 50))
|
||||
# vertical
|
||||
self.assertRoughly( 50, PathGeom.speedBetweenPoints(Vector(), Vector(0,0,1), 100, 50))
|
||||
self.assertRoughly( 50, PathGeom.speedBetweenPoints(Vector(0,0,1), Vector(), 100, 50))
|
||||
# 45°
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(), Vector(1,0,1), 100, 50))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(), Vector(0,1,1), 100, 50))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(), Vector(0.707,0.707,1), 100, 50), 0.01)
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(1,0,1), Vector(), 100, 50))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(0,1,1), Vector(), 100, 50))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(0.707,0.707,1), Vector(), 100, 50), 0.01)
|
||||
# 30°
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(), Vector(0.5774,0,1), 100, 50), 0.01)
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(), Vector(0,0.5774,1), 100, 50), 0.01)
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(0.5774,0,1), Vector(), 100, 50), 0.01)
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(0,0.5774,1), Vector(), 100, 50), 0.01)
|
||||
# 60°
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(), Vector(1,0,0.5774), 100, 50), 0.01)
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(), Vector(0,1,0.5774), 100, 50), 0.01)
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(1,0,0.5774), Vector(), 100, 50), 0.01)
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(0,1,0.5774), Vector(), 100, 50), 0.01)
|
||||
|
||||
def test08(self):
|
||||
"""Verify speed interpolation works for different pitches if vSpeed > hSpeed"""
|
||||
# horizontal
|
||||
self.assertRoughly( 50, PathGeom.speedBetweenPoints(Vector(), Vector(1,1,0), 50, 100))
|
||||
self.assertRoughly( 50, PathGeom.speedBetweenPoints(Vector(1,1,0), Vector(), 50, 100))
|
||||
# vertical
|
||||
self.assertRoughly(100, PathGeom.speedBetweenPoints(Vector(), Vector(0,0,1), 50, 100))
|
||||
self.assertRoughly(100, PathGeom.speedBetweenPoints(Vector(0,0,1), Vector(), 50, 100))
|
||||
# 45°
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(), Vector(1,0,1), 50, 100))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(), Vector(0,1,1), 50, 100))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(), Vector(0.707,0.707,1), 50, 100), 0.01)
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(1,0,1), Vector(), 50, 100))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(0,1,1), Vector(), 50, 100))
|
||||
self.assertRoughly( 75, PathGeom.speedBetweenPoints(Vector(0.707,0.707,1), Vector(), 50, 100), 0.01)
|
||||
# 30°
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(), Vector(0.5774,0,1), 50, 100), 0.01)
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(), Vector(0,0.5774,1), 50, 100), 0.01)
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(0.5774,0,1), Vector(), 50, 100), 0.01)
|
||||
self.assertRoughly( 83.33, PathGeom.speedBetweenPoints(Vector(0,0.5774,1), Vector(), 50, 100), 0.01)
|
||||
# 60°
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(), Vector(1,0,0.5774), 50, 100), 0.01)
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(), Vector(0,1,0.5774), 50, 100), 0.01)
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(1,0,0.5774), Vector(), 50, 100), 0.01)
|
||||
self.assertRoughly( 66.66, PathGeom.speedBetweenPoints(Vector(0,1,0.5774), Vector(), 50, 100), 0.01)
|
||||
|
||||
def test10(self):
|
||||
"""Verify proper geometry objects for G1 and G01 commands are created."""
|
||||
spt = Vector(1,2,3)
|
||||
self.assertLine(PathGeom.edgeForCmd(Path.Command('G1', {'X': 7, 'Y': 2, 'Z': 3}), spt), spt, Vector(7, 2, 3))
|
||||
self.assertLine(PathGeom.edgeForCmd(Path.Command('G01', {'X': 1, 'Y': 3, 'Z': 5}), spt), spt, Vector(1, 3, 5))
|
||||
|
||||
def test15(self):
|
||||
"""Verify proper feed rate for G1 commands is assigned."""
|
||||
pass
|
||||
|
||||
def test20(self):
|
||||
"""Verify proper geometry for arcs in the XY-plane are created."""
|
||||
p1 = Vector(0, -1, 2)
|
||||
@@ -262,7 +318,6 @@ class TestPathGeom(PathTestBase):
|
||||
|
||||
self.assertCommandEqual(cmds(center, radius), cmd('G3', Vector(15, 10, 0), Vector(-5, 0, 0)))
|
||||
|
||||
|
||||
def test50(self):
|
||||
"""Verify proper wire(s) aggregation from a Path."""
|
||||
commands = []
|
||||
@@ -448,3 +503,5 @@ class TestPathGeom(PathTestBase):
|
||||
|
||||
edge = Part.Edge(Part.BSplineCurve([Vector(-8,4,0), Vector(1,-5,0), Vector(5,11,0), Vector(12,-5,0)], weights=[2,3,5,7]))
|
||||
self.assertEdgeShapesMatch(edge, PathGeom.flipEdge(edge))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user