Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed segmentation of xy-plane arcs, made # segments factor a property.
  • Loading branch information
mlampert committed Jan 13, 2017
1 parent 0c34f1b commit e76333f
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 16 deletions.
27 changes: 18 additions & 9 deletions src/Mod/Path/PathScripts/PathDressupHoldingTags.py
Expand Up @@ -287,21 +287,22 @@ def bbShow(self):


class MapWireToTag:
def __init__(self, edge, tag, i):
def __init__(self, edge, tag, i, segm):
debugEdge(edge, 'MapWireToTag(%.2f, %.2f, %.2f)' % (i.x, i.y, i.z))
self.tag = tag
self.segm = segm
if PathGeom.pointsCoincide(edge.valueAt(edge.FirstParameter), i):
tail = edge
self.commands = []
debugEdge(tail, '.........=')
elif PathGeom.pointsCoincide(edge.valueAt(edge.LastParameter), i):
debugEdge(edge, '++++++++ .')
self.commands = PathGeom.cmdsForEdge(edge)
self.commands = PathGeom.cmdsForEdge(edge, segm=segm)
tail = None
else:
e, tail = PathGeom.splitEdgeAt(edge, i)
debugEdge(e, '++++++++ .')
self.commands = PathGeom.cmdsForEdge(e)
self.commands = PathGeom.cmdsForEdge(e, segm=segm)
debugEdge(tail, '.........-')
self.initialEdge = edge
self.tail = tail
Expand Down Expand Up @@ -485,7 +486,7 @@ def commandsForEdges(self):
commands = []
for e,flip in self.orderAndFlipEdges(self.cleanupEdges(shape.Edges)):
debugEdge(e, '++++++++ %s' % ('<' if flip else '>'), False)
commands.extend(PathGeom.cmdsForEdge(e, flip, False))
commands.extend(PathGeom.cmdsForEdge(e, flip, False, self.segm))
return commands
return []

Expand Down Expand Up @@ -705,9 +706,10 @@ def __init__(self, obj):
obj.addProperty("App::PropertyLength", "Width", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Width of tags."))
obj.addProperty("App::PropertyLength", "Height", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Height of tags."))
obj.addProperty("App::PropertyAngle", "Angle", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Angle of tag plunge and ascent."))
obj.addProperty("App::PropertyLength", "Radius", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Radius of the fillet on the top the tag."))
obj.addProperty("App::PropertyLength", "Radius", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Radius of the fillet for the tag."))
obj.addProperty("App::PropertyVectorList", "Positions", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Locations of insterted holding tags"))
obj.addProperty("App::PropertyIntegerList", "Disabled", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Ids of disabled holding tags"))
obj.addProperty("App::PropertyInteger", "SegmentationFactor", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Factor determining the # segments used to approximate rounded tags."))
obj.Proxy = self

def __getstate__(self):
Expand Down Expand Up @@ -738,7 +740,7 @@ def isValidTagStartIntersection(self, edge, i):
return False
return True

def createPath(self, edges, tags, rapid):
def createPath(self, obj, edges, tags, rapid):
#print("createPath")
commands = []
lastEdge = 0
Expand All @@ -748,6 +750,13 @@ def createPath(self, edges, tags, rapid):
inters = None
edge = None

segm = 50
if hasattr(obj, 'SegmentationFactor'):
segm = obj.SegmentationFactor
if segm <= 0:
segm = 50
obj.SegmentationFactor = 50

self.mappers = []
mapper = None

Expand All @@ -773,7 +782,7 @@ def createPath(self, edges, tags, rapid):
t += 1
i = tags[tIndex].intersects(edge, edge.FirstParameter)
if i and self.isValidTagStartIntersection(edge, i):
mapper = MapWireToTag(edge, tags[tIndex], i)
mapper = MapWireToTag(edge, tags[tIndex], i, segm)
self.mappers.append(mapper)
edge = mapper.tail

Expand All @@ -786,7 +795,7 @@ def createPath(self, edges, tags, rapid):
v = edge.Vertexes[1]
commands.append(Path.Command('G0', {'X': v.X, 'Y': v.Y, 'Z': v.Z}))
else:
commands.extend(PathGeom.cmdsForEdge(edge))
commands.extend(PathGeom.cmdsForEdge(edge, segm=segm))
edge = None
t = 0

Expand Down Expand Up @@ -881,7 +890,7 @@ def processTags(self, obj):
#else:
# debugCylinder(tag.originAt(self.pathData.minZ), tag.fullWidth()/2, tag.actualHeight, "tag-%02d" % tagID)

obj.Path = self.createPath(self.pathData.edges, self.tags, self.pathData.rapid)
obj.Path = self.createPath(obj, self.pathData.edges, self.tags, self.pathData.rapid)
#print("execute - done")

def setup(self, obj, generate=False):
Expand Down
14 changes: 7 additions & 7 deletions src/Mod/Path/PathScripts/PathGeom.py
Expand Up @@ -145,15 +145,15 @@ def xy(cls, point):
return Vector(point.x, point.y, 0)

@classmethod
def cmdsForEdge(cls, edge, flip = False, useHelixForBSpline = True):
"""(edge, flip = False, useHelixForBSpline = True) -> List(Path.Command)
def cmdsForEdge(cls, edge, flip = False, useHelixForBSpline = True, segm = 50):
"""(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.
If useHelixForBSpline is True an Edge based on a BSplineCurve is considered
to represent a helix and results in G2 or G3 command. Otherwise edge has
no direct Path.Command mapping and will be approximated by straight segments.
Approximation is also the approach for edges that are neither straight lines
nor arcs (nor helixes)."""
segm is a factor for the segmentation of arbitrary curves not mapped to G1/2/3
commands. The higher the value the more segments will be used."""
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:
Expand All @@ -166,12 +166,12 @@ def cmdsForEdge(cls, edge, flip = False, useHelixForBSpline = True):
p1 = pt
p3 = edge.valueAt(edge.LastParameter)
p2 = edge.valueAt((edge.FirstParameter + edge.LastParameter)/2)
if (type(edge.Curve) == Part.Circle and cls.pointsCoincide(edge.Curve.Axis, Vector(0, 0, 1))) or (useHelixForBSpline and type(edge.Curve) == Part.BSplineCurve):
if (type(edge.Curve) == Part.Circle and cls.isRoughly(edge.Curve.Axis.x, 0) and cls.isRoughly(edge.Curve.Axis.y, 0)) or (useHelixForBSpline and type(edge.Curve) == Part.BSplineCurve):
if Side.Left == Side.of(p2 - p1, p3 - p2):
cmd = 'G3'
else:
cmd = 'G2'
print("**** (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f)" % (p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z))
#print("**** (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f)" % (p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z))
pd = Part.Circle(PathGeom.xy(p1), PathGeom.xy(p2), PathGeom.xy(p3)).Center

pa = PathGeom.xy(p1)
Expand All @@ -191,7 +191,7 @@ def cmdsForEdge(cls, edge, flip = False, useHelixForBSpline = True):
return [ Path.Command('G1', {'X': p3.x, 'Y': p3.y, 'Z': p3.z}) ]
# at this point pixellation is all we can do
commands = []
segments = int(math.ceil((deviation / eStraight.Length) * 1000))
segments = int(math.ceil((deviation / eStraight.Length) * segm))
#print("**** pixellation with %d segments" % segments)
dParameter = (edge.LastParameter - edge.FirstParameter) / segments
for i in range(0, segments):
Expand Down

0 comments on commit e76333f

Please sign in to comment.