Skip to content

Commit

Permalink
Path: convert pathmill face to use tc tools
Browse files Browse the repository at this point in the history
  • Loading branch information
sliptonic authored and yorikvanhavre committed Mar 21, 2017
1 parent 2dee821 commit 9e4a6fe
Showing 1 changed file with 59 additions and 112 deletions.
171 changes: 59 additions & 112 deletions src/Mod/Path/PathScripts/PathMillFace.py
Expand Up @@ -35,7 +35,7 @@
import PathScripts.PathLog as PathLog

LOG_MODULE = 'PathMillFace'
PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE)
PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
PathLog.trackModule()

FreeCADGui = None
Expand All @@ -58,55 +58,44 @@ def translate(context, text, disambig=None):
class ObjectFace:

def __init__(self, obj):
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","The base geometry of this object"))
obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Make False, to prevent operation from generating code"))
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","An optional comment for this profile"))
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","User Assigned Label"))

obj.addProperty("App::PropertyLinkSubList", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The base geometry of this object"))
obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "Make False, to prevent operation from generating code"))
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "An optional comment for this profile"))
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "User Assigned Label"))
obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The tool controller that will be used to calculate the path"))

# Tool Properties
# obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber", "Tool", QtCore.QT_TRANSLATE_NOOP("App::Property","The tool number in use"))
# obj.ToolNumber = (0, 0, 1000, 0)
# obj.setEditorMode('ToolNumber', 1) # make this read only
# obj.addProperty("App::PropertyString", "ToolDescription", "Tool", QtCore.QT_TRANSLATE_NOOP("App::Property","The description of the tool "))
# obj.setEditorMode('ToolDescription', 1) # make this read only

# Depth Properties
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","The height needed to clear clamps and obstructions"))
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Rapid Safety Height between locations."))
obj.addProperty("App::PropertyFloatConstraint", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Incremental Step Down of Tool"))
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "The height needed to clear clamps and obstructions"))
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Rapid Safety Height between locations."))
obj.addProperty("App::PropertyFloatConstraint", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Incremental Step Down of Tool"))
obj.StepDown = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Starting Depth of Tool- first cut depth in Z"))
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Final Depth of Tool- lowest value in Z"))
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Maximum material removed on final pass."))
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Starting Depth of Tool- first cut depth in Z"))
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Final Depth of Tool- lowest value in Z"))
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Maximum material removed on final pass."))

# Face Properties
obj.addProperty("App::PropertyEnumeration", "CutMode", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW"))
obj.addProperty("App::PropertyEnumeration", "CutMode", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW"))
obj.CutMode = ['Climb', 'Conventional']
obj.addProperty("App::PropertyDistance", "PassExtension", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","How far the cutter should extend past the boundary"))
obj.addProperty("App::PropertyEnumeration", "StartAt", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Start Faceing at center or boundary"))
obj.addProperty("App::PropertyDistance", "PassExtension", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "How far the cutter should extend past the boundary"))
obj.addProperty("App::PropertyEnumeration", "StartAt", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "Start Faceing at center or boundary"))
obj.StartAt = ['Center', 'Edge']
obj.addProperty("App::PropertyPercent", "StepOver", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Percent of cutter diameter to step over on each pass"))
#obj.StepOver = (1, 1, 100, 1)
obj.addProperty("App::PropertyBool", "KeepToolDown", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Attempts to avoid unnecessary retractions."))
obj.addProperty("App::PropertyBool", "ZigUnidirectional", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Lifts tool at the end of each pass to respect cut mode."))
obj.addProperty("App::PropertyBool", "UseZigZag", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Use Zig Zag pattern to clear area."))
obj.addProperty("App::PropertyFloat", "ZigZagAngle", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Angle of the zigzag pattern"))
obj.addProperty("App::PropertyEnumeration", "BoundaryShape", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Shape to use for calculating Boundary"))
obj.addProperty("App::PropertyPercent", "StepOver", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "Percent of cutter diameter to step over on each pass"))
obj.addProperty("App::PropertyBool", "KeepToolDown", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "Attempts to avoid unnecessary retractions."))
obj.addProperty("App::PropertyBool", "ZigUnidirectional", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "Lifts tool at the end of each pass to respect cut mode."))
obj.addProperty("App::PropertyBool", "UseZigZag", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "Use Zig Zag pattern to clear area."))
obj.addProperty("App::PropertyFloat", "ZigZagAngle", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "Angle of the zigzag pattern"))
obj.addProperty("App::PropertyEnumeration", "BoundaryShape", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "Shape to use for calculating Boundary"))
obj.BoundaryShape = ['Perimeter', 'Boundbox']


# Start Point Properties
obj.addProperty("App::PropertyVector", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property","The start point of this path"))
obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property","make True, if specifying a Start Point"))
obj.addProperty("App::PropertyVector", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "The start point of this path"))
obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if specifying a Start Point"))

obj.Proxy = self

def onChanged(self, obj, prop):

if prop == "UserLabel":
#obj.Label = obj.UserLabel + " :" + obj.ToolDescription
self.setLabel(obj)

if prop == "StepOver":
Expand Down Expand Up @@ -143,7 +132,6 @@ def _guessDepths(self, obj, ss, sub=""):
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0


def addFacebase(self, obj, ss, sub=""):
baselist = obj.Base
if baselist is None:
Expand All @@ -154,8 +142,8 @@ def addFacebase(self, obj, ss, sub=""):
item = (ss, sub)
if item in baselist:
FreeCAD.Console.PrintWarning(translate("Path", "this object already in the list" + "\n"))
elif PathUtils.findParentJob(obj).Base.Name != ss.Name:
FreeCAD.Console.PrintWarning(translate("Path", "Please select features from the Job model object" +"\n"))
elif PathUtils.findParentJob(obj).Base.Name != ss.Name:
FreeCAD.Console.PrintWarning(translate("Path", "Please select features from the Job model object" + "\n"))
else:
baselist.append(item)
obj.Base = baselist
Expand Down Expand Up @@ -233,64 +221,39 @@ def execute(self, obj):
if toolLoad is None or toolLoad.ToolNumber == 0:
FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
return

# if not obj.Active:
# path = Path.Path("(inactive operation)")
# obj.Path = path
# obj.ViewObject.Visibility = False
# return

# #Tool may have changed. Refresh data
# toolLoad = PathUtils.getLastToolLoad(obj)
# if toolLoad is None or toolLoad.ToolNumber == 0:
# self.vertFeed = 100
# self.horizFeed = 100
# self.vertRapid = 100
# self.horizRrapid = 100
# self.radius = 0.25
# obj.ToolNumber = 0
# obj.ToolDescription = "UNDEFINED"
else:
self.vertFeed = toolLoad.VertFeed.Value
self.horizFeed = toolLoad.HorizFeed.Value
self.vertRapid = toolLoad.VertRapid.Value
self.horizRapid = toolLoad.HorizRapid.Value
tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
tool = toolLoad.Proxy.getTool(toolLoad)

if tool.Diameter == 0:
#self.radius = 0.25
FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
return

else:
self.radius = tool.Diameter/2
#obj.ToolNumber = toolLoad.ToolNumber
#obj.ToolDescription = toolLoad.Name

#Build preliminary comments
# Build preliminary comments
output = ""
output += "(" + obj.Label + ")"

# if obj.UserLabel == "":
# obj.Label = obj.Name + " :" + obj.ToolDescription
# else:
# obj.Label = obj.UserLabel + " :" + obj.ToolDescription

#Facing is done either against base objects
# Facing is done either against base objects
if obj.Base:
PathLog.debug("obj.Base: {}".format (obj.Base))
PathLog.debug("obj.Base: {}".format(obj.Base))
faces = []
for b in obj.Base:
for sub in b[1]:
shape = getattr(b[0].Shape, sub)
if isinstance (shape, Part.Face):
if isinstance(shape, Part.Face):
faces.append(shape)
else:
PathLog.debug('The base subobject is not a face')
return
planeshape = Part.makeCompound(faces)
PathLog.info("Working on a collection of faces {}".format(faces))

#If no base object, do planing of top surface of entire model
# If no base object, do planing of top surface of entire model
else:
parentJob = PathUtils.findParentJob(obj)
if parentJob is None:
Expand All @@ -303,36 +266,33 @@ def execute(self, obj):
planeshape = baseobject.Shape
PathLog.info("Working on a shape {}".format(baseobject.Name))

#if user wants the boundbox, calculate that
# if user wants the boundbox, calculate that
PathLog.info("Boundary Shape: {}".format(obj.BoundaryShape))
if obj.BoundaryShape == 'Boundbox':
bb = planeshape.BoundBox
bbperim = Part.makeBox(bb.XLength, bb.YLength, 1, Vector(bb.XMin, bb.YMin, bb.ZMin), Vector(0,0,1))
contourwire = TechDraw.findShapeOutline(bbperim, 1, Vector(0,0,1))
bbperim = Part.makeBox(bb.XLength, bb.YLength, 1, Vector(bb.XMin, bb.YMin, bb.ZMin), Vector(0, 0, 1))
contourwire = TechDraw.findShapeOutline(bbperim, 1, Vector(0, 0, 1))
else:
contourwire = TechDraw.findShapeOutline(planeshape, 1, Vector(0,0,1))

#zHeight = contourwire.BoundBox.ZMin

pocket = Path.Area(PocketMode=4,SectionCount=-1,SectionMode=1,Stepdown=0.499)
pocket.setParams(PocketExtraOffset = obj.PassExtension.Value, ToolRadius = self.radius)
pocket.add(planeshape, op=1)
#Part.show(contourwire)
path = Path.fromShapes(pocket.getShape())


# edgelist = contourwire.Edges
# edgelist = Part.__sortEdges__(edgelist)

# #use libarea to build the pattern
# a = area.Area()
# c = PathScripts.PathKurveUtils.makeAreaCurve(edgelist, 'CW')
# PathLog.debug(c.text())
# a.append(c)
# a.Reorder()
# output += self.buildpathlibarea(obj, a)

# path = Path.Path(output)
contourwire = TechDraw.findShapeOutline(planeshape, 1, Vector(0, 0, 1))

# pocket = Path.Area(PocketMode=4,SectionCount=-1,SectionMode=1,Stepdown=0.499)
# pocket.setParams(PocketExtraOffset = obj.PassExtension.Value, ToolRadius = self.radius)
# pocket.add(planeshape, op=1)
# #Part.show(contourwire)
# path = Path.fromShapes(pocket.getShape())

edgelist = contourwire.Edges
edgelist = Part.__sortEdges__(edgelist)

# use libarea to build the pattern
a = area.Area()
c = PathScripts.PathKurveUtils.makeAreaCurve(edgelist, 'CW')
PathLog.debug(c.text())
a.append(c)
a.Reorder()
output += self.buildpathlibarea(obj, a)

path = Path.Path(output)
if len(path.Commands) == 0:
FreeCAD.Console.PrintMessage(translate("PathMillFace", "The selected settings did not produce a valid path.\n"))

Expand Down Expand Up @@ -402,7 +362,6 @@ def IsActive(self):

def Activated(self):

# zbottom = 0.0
ztop = 10.0

# if everything is ok, execute and register the transaction in the undo/redo stack
Expand Down Expand Up @@ -443,7 +402,7 @@ def Activated(self):

class TaskPanel:
def __init__(self):
#self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/MillFaceEdit.ui")
# self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/MillFaceEdit.ui")
self.form = FreeCADGui.PySideUic.loadUi(":/panels/MillFaceEdit.ui")
self.updating = False

Expand Down Expand Up @@ -476,9 +435,6 @@ def getFields(self):
self.obj.StepDown = FreeCAD.Units.Quantity(self.form.stepDown.text()).Value
if hasattr(self.obj, "PassExtension"):
self.obj.PassExtension = FreeCAD.Units.Quantity(self.form.extraOffset.text()).Value

# if hasattr(self.obj, "UseStartPoint"):
# self.obj.UseStartPoint = self.form.useStartPoint.isChecked()
if hasattr(self.obj, "CutMode"):
self.obj.CutMode = str(self.form.cutMode.currentText())
if hasattr(self.obj, "UseZigZag"):
Expand All @@ -487,8 +443,6 @@ def getFields(self):
self.obj.ZigUnidirectional = self.form.zigZagUnidirectional.isChecked()
if hasattr(self.obj, "ZigZagAngle"):
self.obj.ZigZagAngle = FreeCAD.Units.Quantity(self.form.zigZagAngle.text()).Value
# if hasattr(self.obj, "ZigZagAngle"):
# self.obj.ZigZagAngle = self.form.zigZagAngle.value()
if hasattr(self.obj, "StepOver"):
self.obj.StepOver = self.form.stepOverPercent.value()
if hasattr(self.obj, "BoundaryShape"):
Expand All @@ -511,21 +465,19 @@ def setFields(self):
self.form.useZigZag.setChecked(self.obj.UseZigZag)
self.form.zigZagUnidirectional.setChecked(self.obj.ZigUnidirectional)
self.form.zigZagAngle.setValue(FreeCAD.Units.Quantity(self.obj.ZigZagAngle, FreeCAD.Units.Angle))
# self.form.zigZagAngle.setValue(self.obj.ZigZagAngle)
#self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
self.form.extraOffset.setValue(self.obj.PassExtension.Value)

index = self.form.cutMode.findText(
self.obj.CutMode, QtCore.Qt.MatchFixedString)
if index >=0:
if index >= 0:

self.form.cutMode.blockSignals(True)
self.form.cutMode.setCurrentIndex(index)
self.form.cutMode.blockSignals(False)

index = self.form.boundaryShape.findText(
self.obj.BoundaryShape, QtCore.Qt.MatchFixedString)
if index >=0:
if index >= 0:
self.form.boundaryShape.blockSignals(True)
self.form.boundaryShape.setCurrentIndex(index)
self.form.boundaryShape.blockSignals(False)
Expand All @@ -538,7 +490,7 @@ def setFields(self):
labels = [c.Label for c in controllers]
self.form.uiToolController.addItems(labels)
if self.obj.ToolController is not None:
index = self.form.direction.findText(
index = self.form.uiToolController.findText(
self.obj.ToolController.Label, QtCore.Qt.MatchFixedString)
if index >= 0:
self.form.uiToolController.setCurrentIndex(index)
Expand Down Expand Up @@ -571,7 +523,6 @@ def addBase(self):
for i in self.obj.Base:
for sub in i[1]:
self.form.baseList.addItem(i[0].Name + "." + sub)
#self.obj.Proxy.execute(self.obj)
FreeCAD.ActiveDocument.recompute()

def deleteBase(self):
Expand All @@ -583,19 +534,17 @@ def deleteBase(self):

for i in self.obj.Base:
sublist = []
#baseobj = i[0]
basesubs = i[1]
for sub in basesubs:
if sub != deletesub:
sublist.append(sub)
if len(sublist) >= 1:
newlist.append ((deletebase, tuple(sublist)))
newlist.append((deletebase, tuple(sublist)))

if i[0].Name != d.text().partition(".")[0] and d.text().partition(".")[2] not in i[1]:
newlist.append(i)
self.form.baseList.takeItem(self.form.baseList.row(d))
self.obj.Base = newlist
#self.obj.Proxy.execute(self.obj)
FreeCAD.ActiveDocument.recompute()

def itemActivated(self):
Expand All @@ -622,7 +571,6 @@ def reorderBase(self):
newlist.append(item)
self.obj.Base = newlist

#self.obj.Proxy.execute(self.obj)
FreeCAD.ActiveDocument.recompute()

def getStandardButtons(self):
Expand Down Expand Up @@ -659,7 +607,6 @@ def setupUi(self):

# operation
self.form.cutMode.currentIndexChanged.connect(self.getFields)
#self.form.useStartPoint.clicked.connect(self.getFields)
self.form.extraOffset.editingFinished.connect(self.getFields)
self.form.boundaryShape.currentIndexChanged.connect(self.getFields)
self.form.stepOverPercent.editingFinished.connect(self.getFields)
Expand Down

0 comments on commit 9e4a6fe

Please sign in to comment.