Merge branch 'master' of github.com:FreeCAD/FreeCAD

This commit is contained in:
Yorik van Havre 2017-01-13 11:21:52 -02:00
commit 1ceb71874d
2 changed files with 25 additions and 16 deletions

View File

@ -287,21 +287,22 @@ class Tag:
class MapWireToTag: 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)) debugEdge(edge, 'MapWireToTag(%.2f, %.2f, %.2f)' % (i.x, i.y, i.z))
self.tag = tag self.tag = tag
self.segm = segm
if PathGeom.pointsCoincide(edge.valueAt(edge.FirstParameter), i): if PathGeom.pointsCoincide(edge.valueAt(edge.FirstParameter), i):
tail = edge tail = edge
self.commands = [] self.commands = []
debugEdge(tail, '.........=') debugEdge(tail, '.........=')
elif PathGeom.pointsCoincide(edge.valueAt(edge.LastParameter), i): elif PathGeom.pointsCoincide(edge.valueAt(edge.LastParameter), i):
debugEdge(edge, '++++++++ .') debugEdge(edge, '++++++++ .')
self.commands = PathGeom.cmdsForEdge(edge) self.commands = PathGeom.cmdsForEdge(edge, segm=segm)
tail = None tail = None
else: else:
e, tail = PathGeom.splitEdgeAt(edge, i) e, tail = PathGeom.splitEdgeAt(edge, i)
debugEdge(e, '++++++++ .') debugEdge(e, '++++++++ .')
self.commands = PathGeom.cmdsForEdge(e) self.commands = PathGeom.cmdsForEdge(e, segm=segm)
debugEdge(tail, '.........-') debugEdge(tail, '.........-')
self.initialEdge = edge self.initialEdge = edge
self.tail = tail self.tail = tail
@ -485,7 +486,7 @@ class MapWireToTag:
commands = [] commands = []
for e,flip in self.orderAndFlipEdges(self.cleanupEdges(shape.Edges)): for e,flip in self.orderAndFlipEdges(self.cleanupEdges(shape.Edges)):
debugEdge(e, '++++++++ %s' % ('<' if flip else '>'), False) 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 commands
return [] return []
@ -705,9 +706,10 @@ class ObjectDressup:
obj.addProperty("App::PropertyLength", "Width", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Width of tags.")) 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::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::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::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::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 obj.Proxy = self
def __getstate__(self): def __getstate__(self):
@ -738,7 +740,7 @@ class ObjectDressup:
return False return False
return True return True
def createPath(self, edges, tags, rapid): def createPath(self, obj, edges, tags, rapid):
#print("createPath") #print("createPath")
commands = [] commands = []
lastEdge = 0 lastEdge = 0
@ -748,6 +750,13 @@ class ObjectDressup:
inters = None inters = None
edge = None edge = None
segm = 50
if hasattr(obj, 'SegmentationFactor'):
segm = obj.SegmentationFactor
if segm <= 0:
segm = 50
obj.SegmentationFactor = 50
self.mappers = [] self.mappers = []
mapper = None mapper = None
@ -773,7 +782,7 @@ class ObjectDressup:
t += 1 t += 1
i = tags[tIndex].intersects(edge, edge.FirstParameter) i = tags[tIndex].intersects(edge, edge.FirstParameter)
if i and self.isValidTagStartIntersection(edge, i): if i and self.isValidTagStartIntersection(edge, i):
mapper = MapWireToTag(edge, tags[tIndex], i) mapper = MapWireToTag(edge, tags[tIndex], i, segm)
self.mappers.append(mapper) self.mappers.append(mapper)
edge = mapper.tail edge = mapper.tail
@ -786,7 +795,7 @@ class ObjectDressup:
v = edge.Vertexes[1] v = edge.Vertexes[1]
commands.append(Path.Command('G0', {'X': v.X, 'Y': v.Y, 'Z': v.Z})) commands.append(Path.Command('G0', {'X': v.X, 'Y': v.Y, 'Z': v.Z}))
else: else:
commands.extend(PathGeom.cmdsForEdge(edge)) commands.extend(PathGeom.cmdsForEdge(edge, segm=segm))
edge = None edge = None
t = 0 t = 0
@ -881,7 +890,7 @@ class ObjectDressup:
#else: #else:
# debugCylinder(tag.originAt(self.pathData.minZ), tag.fullWidth()/2, tag.actualHeight, "tag-%02d" % tagID) # 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") #print("execute - done")
def setup(self, obj, generate=False): def setup(self, obj, generate=False):

View File

@ -145,15 +145,15 @@ class PathGeom:
return Vector(point.x, point.y, 0) return Vector(point.x, point.y, 0)
@classmethod @classmethod
def cmdsForEdge(cls, edge, flip = False, useHelixForBSpline = True): def cmdsForEdge(cls, edge, flip = False, useHelixForBSpline = True, segm = 50):
"""(edge, flip = False, useHelixForBSpline = True) -> List(Path.Command) """(edge, flip=False, useHelixForBSpline=True, segm=50) -> List(Path.Command)
Returns a list of Path.Command representing the given edge. Returns a list of Path.Command representing the given edge.
If flip is True the edge is considered to be backwards. If flip is True the edge is considered to be backwards.
If useHelixForBSpline is True an Edge based on a BSplineCurve is considered 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 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. no direct Path.Command mapping and will be approximated by straight segments.
Approximation is also the approach for edges that are neither straight lines segm is a factor for the segmentation of arbitrary curves not mapped to G1/2/3
nor arcs (nor helixes).""" commands. The higher the value the more segments will be used."""
pt = edge.valueAt(edge.LastParameter) if not flip else edge.valueAt(edge.FirstParameter) pt = edge.valueAt(edge.LastParameter) if not flip else edge.valueAt(edge.FirstParameter)
params = {'X': pt.x, 'Y': pt.y, 'Z': pt.z} params = {'X': pt.x, 'Y': pt.y, 'Z': pt.z}
if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment: if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment:
@ -166,12 +166,12 @@ class PathGeom:
p1 = pt p1 = pt
p3 = edge.valueAt(edge.LastParameter) p3 = edge.valueAt(edge.LastParameter)
p2 = edge.valueAt((edge.FirstParameter + edge.LastParameter)/2) 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): if Side.Left == Side.of(p2 - p1, p3 - p2):
cmd = 'G3' cmd = 'G3'
else: else:
cmd = 'G2' 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 pd = Part.Circle(PathGeom.xy(p1), PathGeom.xy(p2), PathGeom.xy(p3)).Center
pa = PathGeom.xy(p1) pa = PathGeom.xy(p1)
@ -191,7 +191,7 @@ class PathGeom:
return [ Path.Command('G1', {'X': p3.x, 'Y': p3.y, 'Z': p3.z}) ] return [ Path.Command('G1', {'X': p3.x, 'Y': p3.y, 'Z': p3.z}) ]
# at this point pixellation is all we can do # at this point pixellation is all we can do
commands = [] commands = []
segments = int(math.ceil((deviation / eStraight.Length) * 1000)) segments = int(math.ceil((deviation / eStraight.Length) * segm))
#print("**** pixellation with %d segments" % segments) #print("**** pixellation with %d segments" % segments)
dParameter = (edge.LastParameter - edge.FirstParameter) / segments dParameter = (edge.LastParameter - edge.FirstParameter) / segments
for i in range(0, segments): for i in range(0, segments):