Switched engrave to use path-geom tools

This commit is contained in:
Markus Lampert
2018-06-09 00:18:50 -07:00
committed by wmayer
parent d6d26b6a89
commit f0e6b69690

View File

@@ -33,6 +33,9 @@ import PathScripts.PathUtils as PathUtils
import TechDraw
import traceback
from DraftGeomUtils import geomType
from PathScripts.PathGeom import PathGeom
from PathScripts.PathPreferences import PathPreferences
from PySide import QtCore
__doc__ = "Class and implementation of Path Engrave operation"
@@ -56,7 +59,7 @@ def adjustWirePlacement(obj, shape, wires):
#pmntSupport = shape.Support[0][0].Placement
pmntBase = job.Base.Placement
pmnt = pmntBase.multiply(pmntSupport.inverse().multiply(pmntShape))
PathLog.debug("pmnt = %s" % pmnt)
#PathLog.debug("pmnt = %s" % pmnt)
newWires = []
for w in wires:
edges = []
@@ -81,15 +84,32 @@ class ObjectEngrave(PathOp.ObjectOp):
'''opFeatures(obj) ... return all standard features and edges based geomtries'''
return PathOp.FeatureTool | PathOp.FeatureDepths | PathOp.FeatureHeights | PathOp.FeatureStepDown | PathOp.FeatureBaseEdges;
def setupAdditionalProperties(self, obj):
if not hasattr(obj, 'BaseShapes'):
obj.addProperty("App::PropertyLinkList", "BaseShapes", "Path", QtCore.QT_TRANSLATE_NOOP("PathEngrave", "Additional base objects to be engraved"))
obj.setEditorMode('BaseShapes', 2) # hide
if not hasattr(obj, 'BaseObject'):
obj.addProperty("App::PropertyLink", "BaseObject", "Path", QtCore.QT_TRANSLATE_NOOP("PathEngrave", "Additional base objects to be engraved"))
obj.setEditorMode('BaseObject', 2) # hide
def initOperation(self, obj):
'''initOperation(obj) ... create engraving specific properties.'''
obj.addProperty("App::PropertyInteger", "StartVertex", "Path", QtCore.QT_TRANSLATE_NOOP("PathEngrave", "The vertex index to start the path from"))
obj.addProperty("App::PropertyLinkList", "BaseShapes", "Path", QtCore.QT_TRANSLATE_NOOP("PathEngrave", "Additional base objects to be engraved"))
self.setupAdditionalProperties(obj)
def onDocumentRestored(self, obj):
# upgrade ...
super(self.__class__, self).onDocumentRestored(obj)
self.setupAdditionalProperties(obj)
def opExecute(self, obj):
'''opExecute(obj) ... process engraving operation'''
PathLog.track()
job = PathUtils.findParentJob(obj)
if job and job.Base:
obj.BaseObject = job.Base
zValues = []
if obj.StepDown.Value != 0:
z = obj.StartDepth.Value - obj.StepDown.Value
@@ -100,57 +120,62 @@ class ObjectEngrave(PathOp.ObjectOp):
zValues.append(obj.FinalDepth.Value)
self.zValues = zValues
output = ''
try:
if self.baseobject.isDerivedFrom('Sketcher::SketchObject') or \
self.baseobject.isDerivedFrom('Part::Part2DObject') or \
hasattr(self.baseobject, 'ArrayType'):
PathLog.track()
output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
# we only consider the outer wire if this is a Face
wires = []
for w in self.baseobject.Shape.Wires:
tempedges = PathUtils.cleanedges(w.Edges, 0.5)
wires.append(Part.Wire(tempedges))
output += self.buildpathocc(obj, wires, zValues)
wires.append(Part.Wire(w.Edges))
self.buildpathocc(obj, wires, zValues)
self.wires = wires
elif isinstance(self.baseobject.Proxy, ArchPanel.PanelSheet): # process the sheet
PathLog.track()
wires = []
for tag in self.baseobject.Proxy.getTags(self.baseobject, transform=True):
output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
tagWires = []
for w in tag.Wires:
tempedges = PathUtils.cleanedges(w.Edges, 0.5)
tagWires.append(Part.Wire(tempedges))
output += self.buildpathocc(obj, tagWires, zValues)
tagWires.append(Part.Wire(w.Edges))
self.buildpathocc(obj, tagWires, zValues)
wires.extend(tagWires)
self.wires = wires
elif obj.Base:
PathLog.track()
wires = []
for base, subs in obj.Base:
edges = []
for sub in subs:
edges.extend(base.Shape.getElement(sub).Edges)
shapeWires = adjustWirePlacement(obj, base, TechDraw.edgeWalker(edges))
wires.extend(shapeWires)
output += self.buildpathocc(obj, wires, zValues)
#edges = []
#for sub in subs:
# edges.extend(base.Shape.getElement(sub).Edges)
#shapeWires = adjustWirePlacement(obj, base, TechDraw.edgeWalker(edges))
#wires.extend(shapeWires)
for feature in subs:
sub = base.Shape.getElement(feature)
if sub.Wires:
shapeWires = sub.Wires
else:
shapeWires = [Part.Wire(sub.Edges)]
wires.extend(adjustWirePlacement(obj, base, shapeWires))
self.buildpathocc(obj, wires, zValues)
self.wires = wires
elif not obj.BaseShapes:
PathLog.track()
raise ValueError(translate('PathEngrave', "Unknown baseobject type for engraving (%s)") % (obj.Base))
if obj.BaseShapes:
PathLog.track()
wires = []
for shape in obj.BaseShapes:
shapeWires = adjustWirePlacement(obj, shape, shape.Shape.Wires)
output += self.buildpathocc(obj, shapeWires, zValues)
self.buildpathocc(obj, shapeWires, zValues)
wires.extend(shapeWires)
self.wires = wires
output += "G0 Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
except Exception as e:
PathLog.error(e)
@@ -161,8 +186,6 @@ class ObjectEngrave(PathOp.ObjectOp):
'''buildpathocc(obj, wires, zValues) ... internal helper function to generate engraving commands.'''
PathLog.track()
output = ""
for wire in wires:
offset = wire
@@ -178,53 +201,35 @@ class ObjectEngrave(PathOp.ObjectOp):
if not last:
# we set the first move to our first point
last = edge.Vertexes[0].Point
output += "G0" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.horizRapid) # Rapid to starting position
if len(offset.Edges) > 1:
e2 = offset.Edges[1]
if not PathGeom.pointsCoincide(edge.Vertexes[-1].Point, e2.Vertexes[0].Point) and not PathGeom.pointsCoincide(edge.Vertexes[-1].Point, e2.Vertexes[-1].Point):
PathLog.debug("flip first edge")
last = edge.Vertexes[-1].Point
else:
PathLog.debug("original first edge")
else:
PathLog.debug("not enough edges to flip")
self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'Z': obj.ClearanceHeight.Value, 'F': self.horizRapid}))
output += "G0" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(obj.SafeHeight.Value) + "F " + PathUtils.fmt(self.horizRapid) # Rapid to safe height
self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))
output += "G1" + " X" + PathUtils.fmt(last.x) + " Y" + PathUtils.fmt(last.y) + " Z" + PathUtils.fmt(z) + "F " + PathUtils.fmt(self.vertFeed) + "\n" # Vertical feed to depth
self.commandlist.append(Path.Command('G0', {'X': last.x, 'Y': last.y, 'Z': z, 'F': self.vertFeed}))
if isinstance(edge.Curve, Part.Circle):
point = edge.Vertexes[-1].Point
if point == last: # edges can come flipped
point = edge.Vertexes[0].Point
center = edge.Curve.Center
relcenter = center.sub(last)
v1 = last.sub(center)
v2 = point.sub(center)
if v1.cross(v2).z < 0:
output += "G2"
else:
output += "G3"
output += " X" + PathUtils.fmt(point.x) + " Y" + PathUtils.fmt(point.y) + " Z" + PathUtils.fmt(z)
output += " I" + PathUtils.fmt(relcenter.x) + " J" + PathUtils.fmt(relcenter.y) + " K" + PathUtils.fmt(relcenter.z)
output += " F " + PathUtils.fmt(self.horizFeed)
output += "\n"
cmd = 'G2' if v1.cross(v2).z < 0 else 'G3'
args = {}
args['X'] = point.x
args['Y'] = point.y
args['Z'] = z
args['I'] = relcenter.x
args['J'] = relcenter.y
args['K'] = relcenter.z
args['F'] = self.horizFeed
self.commandlist.append(Path.Command(cmd, args))
last = point
if PathGeom.pointsCoincide(last, edge.Vertexes[0].Point):
for cmd in PathGeom.cmdsForEdge(edge):
params = cmd.Parameters
params.update({'Z': z, 'F': self.horizFeed})
self.commandlist.append(Path.Command(cmd.Name, params))
last = edge.Vertexes[-1].Point
else:
point = edge.Vertexes[-1].Point
if point == last: # edges can come flipped
point = edge.Vertexes[0].Point
output += "G1 X" + PathUtils.fmt(point.x) + " Y" + PathUtils.fmt(point.y) + " Z" + PathUtils.fmt(z)
output += " F " + PathUtils.fmt(self.horizFeed)
output += "\n"
self.commandlist.append(Path.Command('G1', {'X': point.x, 'Y': point.y, 'Z': z, 'F': self.horizFeed}))
last = point
output += "G0 Z " + PathUtils.fmt(obj.ClearanceHeight.Value)
for cmd in PathGeom.cmdsForEdge(edge, True):
params = cmd.Parameters
params.update({'Z': z, 'F': self.horizFeed})
self.commandlist.append(Path.Command(cmd.Name, params))
last = edge.Vertexes[0].Point
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
return output
if self.commandlist:
self.commandlist.pop()
def opSetDefaultValues(self, obj):
'''opSetDefaultValues(obj) ... set depths for engraving'''