diff --git a/src/Mod/Path/Gui/Resources/panels/PathEdit.ui b/src/Mod/Path/Gui/Resources/panels/PathEdit.ui
index 6159a4239c..63964c629c 100644
--- a/src/Mod/Path/Gui/Resources/panels/PathEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/PathEdit.ui
@@ -112,8 +112,8 @@
0
0
- 96
- 26
+ 456
+ 1203
@@ -386,8 +386,8 @@
0
0
- 356
- 893
+ 456
+ 1203
@@ -1105,8 +1105,8 @@
0
0
- 325
- 180
+ 456
+ 1203
diff --git a/src/Mod/Path/PathScripts/PathFixture.py b/src/Mod/Path/PathScripts/PathFixture.py
index 9dd94f3d91..23cf80215a 100644
--- a/src/Mod/Path/PathScripts/PathFixture.py
+++ b/src/Mod/Path/PathScripts/PathFixture.py
@@ -25,7 +25,8 @@
import FreeCAD
import FreeCADGui
import Path
-from PySide import QtCore, QtGui
+import PathScripts.PathUtils as PathUtils
+from PySide import QtCore#, QtGui
# Qt tanslation handling
def translate(context, text, disambig=None):
@@ -46,7 +47,10 @@ class Fixture:
obj.Path = Path.Path(str(obj.Fixture))
obj.Label = "Fixture" + str(fixture)
if obj.Active:
- obj.Path = Path.Path(str(obj.Fixture))
+ job = PathUtils.findParentJob(obj)
+ c1 = Path.Command(str(obj.Fixture))
+ c2 = Path.Command("G0" + str(job.Stock.Shape.BoundBox.ZMax))
+ obj.Path = Path.Path([c1, c2])
obj.ViewObject.Visibility = True
else:
obj.Path = Path.Path("(inactive operation)")
diff --git a/src/Mod/Path/PathScripts/PathPost.py b/src/Mod/Path/PathScripts/PathPost.py
index 71ed227f7a..013f1e7eb5 100644
--- a/src/Mod/Path/PathScripts/PathPost.py
+++ b/src/Mod/Path/PathScripts/PathPost.py
@@ -31,7 +31,6 @@ import Path
import PathScripts.PathJob as PathJob
import PathScripts.PathLog as PathLog
import PathScripts.PathPreferences as PathPreferences
-#import PathScripts.PathToolController as PathToolController
import PathScripts.PathUtil as PathUtil
import PathScripts.PathUtils as PathUtils
import os
@@ -43,12 +42,20 @@ from PySide import QtCore, QtGui
LOG_MODULE = PathLog.thisModule()
PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE)
-#PathLog.trackModule(LOG_MODULE)
+
# Qt tanslation handling
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
+
+class _TempObject:
+ Path = None
+ Name = "Fixture"
+ InList = []
+ Label = "Fixture"
+
+
class DlgSelectPostProcessor:
def __init__(self, parent=None):
@@ -84,13 +91,16 @@ class DlgSelectPostProcessor:
return posts[0].text()
return None
+
class CommandPathPost:
+ subpart = 1
def resolveFileName(self, job):
path = PathPreferences.defaultOutputFile()
if job.PostProcessorOutputFile:
path = job.PostProcessorOutputFile
filename = path
+
if '%D' in filename:
D = FreeCAD.ActiveDocument.FileName
if D:
@@ -116,6 +126,13 @@ class CommandPathPost:
M = pref.GetString("MacroPath", FreeCAD.getUserAppDataDir())
filename = filename.replace('%M', M)
+ if '%s' in filename:
+ if job.SplitOutput:
+ filename = filename.replace('%s', '_'+str(self.subpart))
+ self.subpart += 1
+ else:
+ filename = filename.replace('%s', '')
+
policy = PathPreferences.defaultOutputPolicy()
openDialog = policy == 'Open File Dialog'
@@ -156,7 +173,6 @@ class CommandPathPost:
dlg = DlgSelectPostProcessor()
return dlg.exec_()
-
def GetResources(self):
return {'Pixmap': 'Path-Post',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Post", "Post Process"),
@@ -172,7 +188,7 @@ class CommandPathPost:
return False
- def exportObjectsWith(self, objs, job, needFilename = True):
+ def exportObjectsWith(self, objs, job, needFilename=True, filepart=None):
PathLog.track()
# check if the user has a project and has set the default post and
# output filename
@@ -249,41 +265,128 @@ class CommandPathPost:
wcslist = job.Fixtures
else:
wcslist = ['G54']
- PathLog.debug("processing fixtures: {}".format(wcslist))
if hasattr(job, "OrderOutputBy"):
orderby = job.OrderOutputBy
else:
orderby = "Operation"
- PathLog.debug("Order Output by: {}".format(orderby))
if hasattr(job, "SplitOutput"):
split = job.SplitOutput
else:
split = False
- PathLog.debug("Splitting Output: {}".format(split))
postlist = []
if orderby == 'Fixture':
+ PathLog.debug("Ordering by Fixture")
+ # Order by fixture means all operations and tool changes will be completed in one
+ # fixture before moving to the next.
+
+ currTool = None
for f in wcslist:
+ # create an object to serve as the fixture path
+ fobj = _TempObject()
c1 = Path.Command(f)
c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax))
- postlist.append(Path.Path([c1, c2]))
+ fobj.Path = Path.Path([c1, c2])
+ fobj.InList.append(job)
+ sublist = [fobj]
- currTool = None
+ # Now generate the gcode
for obj in job.Operations.Group:
- PathLog.debug("obj: {}".format(obj.Name))
tc = PathUtil.toolControllerForOp(obj)
if tc is not None:
if tc.ToolNumber != currTool:
- postlist.append(tc)
+ sublist.append(tc)
+ PathLog.debug("Appending TC: {}".format(tc.Name))
currTool = tc.ToolNumber
- postlist.append(obj)
+ sublist.append(obj)
+ postlist.append(sublist)
+
+ elif orderby == 'Tool':
+ PathLog.debug("Ordering by Tool")
+ # Order by tool means tool changes are minimized.
+ # all operations with the current tool are processed in the current
+ # fixture before moving to the next fixture.
+
+ currTool = None
+ fixturelist = []
+ for f in wcslist:
+ # create an object to serve as the fixture path
+ fobj = _TempObject()
+ c1 = Path.Command(f)
+ c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax))
+ fobj.Path = Path.Path([c1, c2])
+ fobj.InList.append(job)
+ fixturelist.append(fobj)
+
+ # Now generate the gcode
+ curlist = [] # list of ops for tool, will repeat for each fixture
+ sublist = [] # list of ops for output splitting
+
+ for idx, obj in enumerate(job.Operations.Group):
+ tc = PathUtil.toolControllerForOp(obj)
+ if tc is None or tc.ToolNumber == currTool:
+ curlist.append(obj)
+ elif tc.ToolNumber != currTool and currTool is None: # first TC
+ sublist.append(tc)
+ curlist.append(obj)
+ currTool = tc.ToolNumber
+ elif tc.ToolNumber != currTool and currTool is not None: # TC
+ for fixture in fixturelist:
+ sublist.append(fixture)
+ sublist.extend(curlist)
+ postlist.append(sublist)
+ sublist = [tc]
+ curlist = [obj]
+ currTool = tc.ToolNumber
+
+ if idx == len(job.Operations.Group) - 1: # Last operation.
+ for fixture in fixturelist:
+ sublist.append(fixture)
+ sublist.extend(curlist)
+ postlist.append(sublist)
+
+ elif orderby == 'Operation':
+ PathLog.debug("Ordering by Operation")
+ # Order by operation means ops are done in each fixture in
+ # sequence.
+ currTool = None
+ fixturelist = []
+ for f in wcslist:
+ # create an object to serve as the fixture path
+ fobj = _TempObject()
+ c1 = Path.Command(f)
+ c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax))
+ fobj.Path = Path.Path([c1, c2])
+ fobj.InList.append(job)
+ fixturelist.append(fobj)
+
+ # Now generate the gcode
+ for obj in job.Operations.Group:
+ sublist = []
+ PathLog.debug("obj: {}".format(obj.Name))
+ for fixture in fixturelist:
+ sublist.append(fixture)
+ tc = PathUtil.toolControllerForOp(obj)
+ if tc is not None:
+ if tc.ToolNumber != currTool:
+ sublist.append(tc)
+ currTool = tc.ToolNumber
+ sublist.append(obj)
+ postlist.append(sublist)
fail = True
rc = ''
- (fail, rc) = self.exportObjectsWith(postlist, job)
+ if split:
+ for slist in postlist:
+ (fail, rc) = self.exportObjectsWith(slist, job)
+ else:
+ finalpostlist = [item for slist in postlist for item in slist]
+ (fail, rc) = self.exportObjectsWith(finalpostlist, job)
+
+ self.subpart = 1
if fail:
FreeCAD.ActiveDocument.abortTransaction()
diff --git a/src/Mod/Path/PathScripts/PathPostProcessor.py b/src/Mod/Path/PathScripts/PathPostProcessor.py
index 7676a0a777..c8eb427990 100644
--- a/src/Mod/Path/PathScripts/PathPostProcessor.py
+++ b/src/Mod/Path/PathScripts/PathPostProcessor.py
@@ -45,11 +45,11 @@ class PostProcessor:
postname = processor + "_post"
namespace = {}
-
+
#can't modify function local scope with exec in python3
exec("import %s as current_post" % postname, namespace)
current_post = namespace['current_post']
-
+
# make sure the script is reloaded if it was previously loaded
# should the script have been imported for the first time above
# then the initialization code of the script gets executed twice