def setDefaultValues(self, obj): '''setDefaultValues(obj) ... base implementation. Do not overwrite, overwrite opSetDefaultValues() instead.''' job = PathUtils.addToJob(obj) obj.Active = True features = self.opFeatures(obj) if FeatureTool & features: if 1 < len(job.Operations.Group): obj.ToolController = PathUtil.toolControllerForOp( job.Operations.Group[-2]) else: obj.ToolController = PathUtils.findToolController(obj) if not obj.ToolController: return None obj.OpToolDiameter = obj.ToolController.Tool.Diameter if FeatureCoolant & features: obj.CoolantMode = job.SetupSheet.CoolantMode if FeatureDepths & features: if self.applyExpression(obj, 'StartDepth', job.SetupSheet.StartDepthExpression): obj.OpStartDepth = 1.0 else: obj.StartDepth = 1.0 if self.applyExpression(obj, 'FinalDepth', job.SetupSheet.FinalDepthExpression): obj.OpFinalDepth = 0.0 else: obj.FinalDepth = 0.0 else: obj.StartDepth = 1.0 if FeatureStepDown & features: if not self.applyExpression(obj, 'StepDown', job.SetupSheet.StepDownExpression): obj.StepDown = '1 mm' if FeatureHeights & features: if job.SetupSheet.SafeHeightExpression: if not self.applyExpression( obj, 'SafeHeight', job.SetupSheet.SafeHeightExpression): obj.SafeHeight = '3 mm' if job.SetupSheet.ClearanceHeightExpression: if not self.applyExpression( obj, 'ClearanceHeight', job.SetupSheet.ClearanceHeightExpression): obj.ClearanceHeight = '5 mm' if FeatureStartPoint & features: obj.UseStartPoint = False self.opSetDefaultValues(obj, job) return job
def executeUpload(self): '''Post process the current Path.Job and upload the resulting g-code into MK. Tag the uploaded g-code with the job and a hash so we can determine if the uploaded version is consistent with what is currently in FC.''' job = self.job if job: currTool = None postlist = [] for obj in job.Operations.Group: tc = PathUtil.toolControllerForOp(obj) if tc is not None: if tc.ToolNumber != currTool: postlist.append(tc) currTool = tc.ToolNumber postlist.append(obj) post = PathPost.CommandPathPost() fail, gcode = post.exportObjectsWith(postlist, job, False) if not fail: print("POST: ", fail) preamble = "(FreeCAD.Job: %s)\n(FreeCAD.File: %s)\n(FreeCAD.Signature: %d)\n" % ( job.Name, job.Document.FileName, MKUtils.pathSignature(job.Path)) buf = io.BytesIO((preamble + gcode).encode()) endpoint = self.mk.instance.endpoint.get('file') if endpoint: ftp = ftplib.FTP() ftp.connect(endpoint.address(), endpoint.port()) ftp.login() ftp.storbinary("STOR %s" % self.mk.RemoteFilename, buf) ftp.quit() sequence = MKUtils.taskModeMDI(self.mk) for tc in job.ToolController: t = tc.Tool radius = float(t.Diameter) / 2 if hasattr( t, 'Diameter') else 0. offset = t.LengthOffset if hasattr( t, 'LengthOffset') else 0. sequence.append( MKCommandTaskExecute( "G10 L1 P%d R%g Z%g" % (tc.ToolNumber, radius, offset))) sequence.extend(MKUtils.taskModeAuto(self.mk)) sequence.append(MKCommandTaskReset(False)) sequence.extend([ MKCommandOpenFile(self.mk.remoteFilePath(), True), MKCommandOpenFile(self.mk.remoteFilePath(), False) ]) sequence.append(MKCommandTaskRun(True)) self.mk['command'].sendCommands(sequence) else: PathLog.error('No endpoint found') else: PathLog.error('Post processing failed')
def setDefaultValues(self, obj): '''setDefaultValues(obj) ... base implementation. Do not overwrite, overwrite opSetDefaultValues() instead.''' job = PathUtils.addToJob(obj) obj.Active = True features = self.opFeatures(obj) if FeatureTool & features: if 1 < len(job.Operations.Group): obj.ToolController = PathUtil.toolControllerForOp(job.Operations.Group[-2]) else: obj.ToolController = PathUtils.findToolController(obj) if not obj.ToolController: return None obj.OpToolDiameter = obj.ToolController.Tool.Diameter if FeatureDepths & features: if self.applyExpression(obj, 'StartDepth', job.SetupSheet.StartDepthExpression): obj.OpStartDepth = 1.0 else: obj.StartDepth = 1.0 if self.applyExpression(obj, 'FinalDepth', job.SetupSheet.FinalDepthExpression): obj.OpFinalDepth = 0.0 else: obj.FinalDepth = 0.0 else: obj.StartDepth = 1.0 if FeatureStepDown & features: if not self.applyExpression(obj, 'StepDown', job.SetupSheet.StepDownExpression): obj.StepDown = '1 mm' if FeatureHeights & features: if job.SetupSheet.SafeHeightExpression: if not self.applyExpression(obj, 'SafeHeight', job.SetupSheet.SafeHeightExpression): obj.SafeHeight = '3 mm' if job.SetupSheet.ClearanceHeightExpression: if not self.applyExpression(obj, 'ClearanceHeight', job.SetupSheet.ClearanceHeightExpression): obj.ClearanceHeight = '5 mm' if FeatureStartPoint & features: obj.UseStartPoint = False self.opSetDefaultValues(obj, job) return job
def executeUpload(self): job = self.job if job: currTool = None postlist = [] for obj in job.Operations.Group: tc = PathUtil.toolControllerForOp(obj) if tc is not None: if tc.ToolNumber != currTool: postlist.append(tc) currTool = tc.ToolNumber postlist.append(obj) post = PathPost.CommandPathPost() fail, gcode = post.exportObjectsWith(postlist, job, False) if not fail: print("POST: ", fail) preamble = "(FreeCAD.Job: %s)\n(FreeCAD.File: %s)\n(FreeCAD.Signature: %d)\n" % ( job.Name, job.Document.FileName, MKUtils.pathSignature(job.Path)) buf = io.BytesIO((preamble + gcode).encode()) endpoint = self.mk.instance.endpoint.get('file') if endpoint: ftp = ftplib.FTP() ftp.connect(endpoint.address(), endpoint.port()) ftp.login() ftp.storbinary("STOR %s" % self.mk.RemoteFilename, buf) ftp.quit() sequence = MKUtils.taskModeMDI(self.mk) for tc in job.ToolController: t = tc.Tool sequence.append( MKCommandTaskExecute("G10 L1 P%d R%g Z%g" % (tc.ToolNumber, t.Diameter / 2., t.LengthOffset))) sequence.extend(MKUtils.taskModeAuto(self.mk)) sequence.append(MKCommandTaskReset(False)) sequence.append( MKCommandOpenFile(self.mk.remoteFilePath(), False)) self.mk['command'].sendCommands(sequence) else: PathLog.error('No endpoint found') else: PathLog.error('Post processing failed')
def Activated(self): PathLog.track() FreeCAD.ActiveDocument.openTransaction( translate("Path_Post", "Post Process the Selected path(s)")) FreeCADGui.addModule("PathScripts.PathPost") # Attempt to figure out what the user wants to post-process # If a job is selected, post that. # If there's only one job in a document, post it. # If a user has selected a subobject of a job, post the job. # If multiple jobs and can't guess, ask them. selected = FreeCADGui.Selection.getSelectionEx() if len(selected) > 1: FreeCAD.Console.PrintError( "Please select a single job or other path object\n") return elif len(selected) == 1: sel = selected[0].Object if sel.Name[:3] == "Job": job = sel elif hasattr(sel, "Path"): try: job = PathUtils.findParentJob(sel) except Exception: # pylint: disable=broad-except job = None else: job = None if job is None: targetlist = [] for o in FreeCAD.ActiveDocument.Objects: if hasattr(o, "Proxy"): if isinstance(o.Proxy, PathJob.ObjectJob): targetlist.append(o.Label) PathLog.debug("Possible post objects: {}".format(targetlist)) if len(targetlist) > 1: form = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobChooser.ui") form.cboProject.addItems(targetlist) r = form.exec_() if r is False: return else: jobname = form.cboProject.currentText() else: jobname = targetlist[0] job = FreeCAD.ActiveDocument.getObject(jobname) PathLog.debug("about to postprocess job: {}".format(job.Name)) # Build up an ordered list of operations and tool changes. # Then post-the ordered list if hasattr(job, "Fixtures"): wcslist = job.Fixtures else: wcslist = ['G54'] if hasattr(job, "OrderOutputBy"): orderby = job.OrderOutputBy else: orderby = "Operation" if hasattr(job, "SplitOutput"): split = job.SplitOutput else: split = False if hasattr(job, "OperatorSetupsheet"): ossheet = job.OperatorSetupsheet else: ossheet = False 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 index, f in enumerate(wcslist): # create an object to serve as the fixture path fobj = _TempObject() c1 = Path.Command(f) fobj.Path = Path.Path([c1]) if index != 0: c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value)) fobj.Path.addCommands(c2) fobj.InList.append(job) sublist = [fobj] # Now generate the gcode for obj in job.Operations.Group: tc = PathUtil.toolControllerForOp(obj) if tc is not None and PathUtil.opProperty(obj, 'Active'): if tc.ToolNumber != currTool: sublist.append(tc) PathLog.debug("Appending TC: {}".format(tc.Name)) currTool = tc.ToolNumber 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 + job.SetupSheet.ClearanceHeightOffset.Value)) 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): # check if the operation is active active = PathUtil.opProperty(obj, 'Active') tc = PathUtil.toolControllerForOp(obj) if tc is None or tc.ToolNumber == currTool and active: curlist.append(obj) elif tc.ToolNumber != currTool and currTool is None and active: # first TC sublist.append(tc) curlist.append(obj) currTool = tc.ToolNumber elif tc.ToolNumber != currTool and currTool is not None and active: # 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 firstFixture = True # Now generate the gcode for obj in job.Operations.Group: if PathUtil.opProperty(obj, 'Active'): sublist = [] PathLog.debug("obj: {}".format(obj.Name)) for f in wcslist: fobj = _TempObject() c1 = Path.Command(f) fobj.Path = Path.Path([c1]) if not firstFixture: c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value)) fobj.Path.addCommands(c2) fobj.InList.append(job) sublist.append(fobj) firstFixture = False 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 = '' # pylint: disable=unused-variable 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() else: FreeCAD.ActiveDocument.commitTransaction() if ossheet: FreeCAD.Console.PrintLog("Create OperatorSetupsheet\n") else: FreeCAD.Console.PrintLog("Do not create OperatorSetupsheet\n") FreeCAD.ActiveDocument.recompute()
def buildPostList(job): """Takes the job and determines the specific objects and order to postprocess Returns a list of objects which can be passed to exportObjectsWith() for final posting.""" wcslist = job.Fixtures orderby = job.OrderOutputBy 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 index, f in enumerate(wcslist): # create an object to serve as the fixture path fobj = _TempObject() c1 = Path.Command(f) fobj.Path = Path.Path([c1]) if index != 0: c2 = Path.Command( "G0 Z" + str( job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value ) ) fobj.Path.addCommands(c2) fobj.InList.append(job) sublist = [fobj] # Now generate the gcode for obj in job.Operations.Group: tc = PathUtil.toolControllerForOp(obj) if tc is not None and PathUtil.opProperty(obj, "Active"): if tc.ToolNumber != currTool: sublist.append(tc) PathLog.debug("Appending TC: {}".format(tc.Name)) currTool = tc.ToolNumber sublist.append(obj) postlist.append((f, 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. toolstring = "None" currTool = None # Build the fixture list 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 + job.SetupSheet.ClearanceHeightOffset.Value ) ) 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 PathLog.track(job.PostProcessorOutputFile) for idx, obj in enumerate(job.Operations.Group): PathLog.track(obj.Label) # check if the operation is active if not getattr(obj, "Active", True): PathLog.track() continue # Determine the proper string for the Op's TC tc = PathUtil.toolControllerForOp(obj) if tc is None: tcstring = "None" elif "%T" in job.PostProcessorOutputFile: tcstring = f"{tc.ToolNumber}" else: tcstring = re.sub(r"[^\w\d-]", "_", tc.Label) PathLog.track(toolstring) 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 toolstring = tcstring elif tc.ToolNumber != currTool and currTool is not None: # TC for fixture in fixturelist: sublist.append(fixture) sublist.extend(curlist) postlist.append((toolstring, sublist)) sublist = [tc] curlist = [obj] currTool = tc.ToolNumber toolstring = tcstring if idx == len(job.Operations.Group) - 1: # Last operation. for fixture in fixturelist: sublist.append(fixture) sublist.extend(curlist) postlist.append((toolstring, sublist)) elif orderby == "Operation": PathLog.debug("Ordering by Operation") # Order by operation means ops are done in each fixture in # sequence. currTool = None firstFixture = True # Now generate the gcode for obj in job.Operations.Group: # check if the operation is active if not getattr(obj, "Active", True): continue sublist = [] PathLog.debug("obj: {}".format(obj.Name)) for f in wcslist: fobj = _TempObject() c1 = Path.Command(f) fobj.Path = Path.Path([c1]) if not firstFixture: c2 = Path.Command( "G0 Z" + str( job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value ) ) fobj.Path.addCommands(c2) fobj.InList.append(job) sublist.append(fobj) firstFixture = False tc = PathUtil.toolControllerForOp(obj) if tc is not None: if job.SplitOutput or (tc.ToolNumber != currTool): sublist.append(tc) currTool = tc.ToolNumber sublist.append(obj) postlist.append((obj.Label, sublist)) if job.SplitOutput: PathLog.track() return postlist else: PathLog.track() finalpostlist = [ ("allitems", [item for slist in postlist for item in slist[1]]) ] return finalpostlist
def Activated(self): PathLog.track() FreeCAD.ActiveDocument.openTransaction( translate("Path_Post", "Post Process the Selected path(s)")) FreeCADGui.addModule("PathScripts.PathPost") # Attempt to figure out what the user wants to post-process # If a job is selected, post that. # If there's only one job in a document, post it. # If a user has selected a subobject of a job, post the job. # If multiple jobs and can't guess, ask them. selected = FreeCADGui.Selection.getSelectionEx() if len(selected) > 1: FreeCAD.Console.PrintError( "Please select a single job or other path object\n") return elif len(selected) == 1: sel = selected[0].Object if sel.Name[:3] == "Job": job = sel elif hasattr(sel, "Path"): try: job = PathUtils.findParentJob(sel) except: job = None else: job = None if job is None: targetlist = [] for o in FreeCAD.ActiveDocument.Objects: if hasattr(o, "Proxy"): if isinstance(o.Proxy, PathJob.ObjectJob): targetlist.append(o.Label) PathLog.debug("Possible post objects: {}".format(targetlist)) if len(targetlist) > 1: form = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobChooser.ui") form.cboProject.addItems(targetlist) r = form.exec_() if r is False: return else: jobname = form.cboProject.currentText() else: jobname = targetlist[0] job = FreeCAD.ActiveDocument.getObject(jobname) PathLog.debug("about to postprocess job: {}".format(job.Name)) # Build up an ordered list of operations and tool changes. # Then post-the ordered list postlist = [] currTool = None 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) currTool = tc.ToolNumber postlist.append(obj) fail = True rc = '' (fail, rc) = self.exportObjectsWith(postlist, job) if fail: FreeCAD.ActiveDocument.abortTransaction() else: FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute()
def Activated(self): PathLog.track() FreeCAD.ActiveDocument.openTransaction( translate("Path_Post", "Post Process the Selected path(s)")) FreeCADGui.addModule("PathScripts.PathPost") # Attempt to figure out what the user wants to post-process # If a job is selected, post that. # If there's only one job in a document, post it. # If a user has selected a subobject of a job, post the job. # If multiple jobs and can't guess, ask them. selected = FreeCADGui.Selection.getSelectionEx() if len(selected) > 1: FreeCAD.Console.PrintError("Please select a single job or other path object\n") return elif len(selected) == 1: sel = selected[0].Object if sel.Name[:3] == "Job": job = sel elif hasattr(sel, "Path"): try: job = PathUtils.findParentJob(sel) except: job = None else: job = None if job is None: targetlist = [] for o in FreeCAD.ActiveDocument.Objects: if hasattr(o, "Proxy"): if isinstance(o.Proxy, PathJob.ObjectJob): targetlist.append(o.Label) PathLog.debug("Possible post objects: {}".format(targetlist)) if len(targetlist) > 1: form = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobChooser.ui") form.cboProject.addItems(targetlist) r = form.exec_() if r is False: return else: jobname = form.cboProject.currentText() else: jobname = targetlist[0] job = FreeCAD.ActiveDocument.getObject(jobname) PathLog.debug("about to postprocess job: {}".format(job.Name)) # Build up an ordered list of operations and tool changes. # Then post-the ordered list postlist = [] currTool = None 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) postlist.append(obj) fail = True rc = '' (fail, rc) = self.exportObjectsWith(postlist, job) if fail: FreeCAD.ActiveDocument.abortTransaction() else: FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute()
def Activated(self): PathLog.track() FreeCAD.ActiveDocument.openTransaction( "Post Process the Selected path(s)") FreeCADGui.addModule("PathScripts.PathPost") # Attempt to figure out what the user wants to post-process # If a job is selected, post that. # If there's only one job in a document, post it. # If a user has selected a subobject of a job, post the job. # If multiple jobs and can't guess, ask them. selected = FreeCADGui.Selection.getSelectionEx() if len(selected) > 1: FreeCAD.Console.PrintError( "Please select a single job or other path object\n") return elif len(selected) == 1: sel = selected[0].Object if sel.Name[:3] == "Job": job = sel elif hasattr(sel, "Path"): try: job = PathUtils.findParentJob(sel) except Exception: job = None else: job = None if job is None: targetlist = [] for o in FreeCAD.ActiveDocument.Objects: if hasattr(o, "Proxy"): if isinstance(o.Proxy, PathJob.ObjectJob): targetlist.append(o.Label) PathLog.debug("Possible post objects: {}".format(targetlist)) if len(targetlist) > 1: jobname, result = QtGui.QInputDialog.getItem( None, translate("Path", "Choose a Path Job"), None, targetlist) if result is False: return else: jobname = targetlist[0] job = FreeCAD.ActiveDocument.getObject(jobname) PathLog.debug("about to postprocess job: {}".format(job.Name)) wcslist = job.Fixtures orderby = job.OrderOutputBy split = job.SplitOutput 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 index, f in enumerate(wcslist): # create an object to serve as the fixture path fobj = _TempObject() c1 = Path.Command(f) fobj.Path = Path.Path([c1]) if index != 0: c2 = Path.Command( "G0 Z" + str(job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value)) fobj.Path.addCommands(c2) fobj.InList.append(job) sublist = [fobj] # Now generate the gcode for obj in job.Operations.Group: tc = PathUtil.toolControllerForOp(obj) if tc is not None and PathUtil.opProperty(obj, "Active"): if tc.ToolNumber != currTool or split is True: sublist.append(tc) PathLog.debug("Appending TC: {}".format(tc.Name)) currTool = tc.ToolNumber 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 + job.SetupSheet.ClearanceHeightOffset.Value)) 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): # check if the operation is active active = PathUtil.opProperty(obj, "Active") tc = PathUtil.toolControllerForOp(obj) if tc is None or tc.ToolNumber == currTool and active: curlist.append(obj) elif (tc.ToolNumber != currTool and currTool is None and active): # first TC sublist.append(tc) curlist.append(obj) currTool = tc.ToolNumber elif (tc.ToolNumber != currTool and currTool is not None and active): # 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 firstFixture = True # Now generate the gcode for obj in job.Operations.Group: if PathUtil.opProperty(obj, "Active"): sublist = [] PathLog.debug("obj: {}".format(obj.Name)) for f in wcslist: fobj = _TempObject() c1 = Path.Command(f) fobj.Path = Path.Path([c1]) if not firstFixture: c2 = Path.Command("G0 Z" + str( job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value)) fobj.Path.addCommands(c2) fobj.InList.append(job) sublist.append(fobj) firstFixture = False tc = PathUtil.toolControllerForOp(obj) if tc is not None: if job.SplitOutput or (tc.ToolNumber != currTool): sublist.append(tc) currTool = tc.ToolNumber sublist.append(obj) postlist.append(sublist) fail = True rc = "" if split: for slist in postlist: (fail, rc, filename) = self.exportObjectsWith(slist, job) if fail: break else: finalpostlist = [item for slist in postlist for item in slist] (fail, rc, filename) = self.exportObjectsWith(finalpostlist, job) self.subpart = 1 if fail: FreeCAD.ActiveDocument.abortTransaction() else: if hasattr(job, "LastPostProcessDate"): job.LastPostProcessDate = str(datetime.now()) if hasattr(job, "LastPostProcessOutput"): job.LastPostProcessOutput = filename FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute()
def buildPostList(self, job): """ Parses the job and returns the list(s) of objects to be written by the post Postlist is a list of lists. Each sublist is intended to be a separate file """ orderby = job.OrderOutputBy fixturelist = [] for f in job.Fixtures: # create an object to serve as the fixture path fobj = _TempObject() fobj.Label = f c1 = Path.Command(f) c2 = Path.Command("G0 Z" + str(job.Stock.Shape.BoundBox.ZMax + job.SetupSheet.ClearanceHeightOffset.Value)) fobj.Path = Path.Path([c1, c2]) # fobj.InList.append(job) fixturelist.append(fobj) 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. for f in fixturelist: scratchpad = [(f, None)] # Now generate the gcode for obj in job.Operations.Group: if not PathUtil.opProperty(obj, "Active"): continue tc = PathUtil.toolControllerForOp(obj) scratchpad.append((obj, tc)) sublist = [] temptool = None for item in scratchpad: if item[1] in [temptool, None]: sublist.append(item[0]) else: sublist.append(item[1]) temptool = item[1] sublist.append(item[0]) 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 # 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): # check if the operation is active active = PathUtil.opProperty(obj, "Active") tc = PathUtil.toolControllerForOp(obj) if not active: # pass on any inactive ops continue if tc is None: curlist.append((obj, None)) continue if tc == currTool: curlist.append((obj, tc)) continue if tc != currTool and currTool is None: # first TC currTool = tc curlist.append((obj, tc)) continue if tc != currTool and currTool is not None: # TC changed if tc.ToolNumber == currTool.ToolNumber: # Same tool /diff params curlist.append((obj, tc)) currTool = tc else: # Actual Toolchange # dump current state to postlist sublist = [] t = None for fixture in fixturelist: sublist.append(fixture) for item in curlist: if item[1] == t: sublist.append(item[0]) else: sublist.append(item[1]) t = item[1] sublist.append(item[0]) postlist.append(sublist) # set up for next tool group currTool = tc curlist = [(obj, tc)] # flush remaining curlist to output sublist = [] t = None for fixture in fixturelist: sublist.append(fixture) for item in curlist: if item[1] == t: sublist.append(item[0]) else: sublist.append(item[1]) t = item[1] sublist.append(item[0]) 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 # firstFixture = True # Now generate the gcode for obj in job.Operations.Group: scratchpad = [] tc = PathUtil.toolControllerForOp(obj) if not PathUtil.opProperty(obj, "Active"): continue PathLog.debug("obj: {}".format(obj.Name)) for f in fixturelist: scratchpad.append((f, None)) scratchpad.append((obj, tc)) sublist = [] temptool = None for item in scratchpad: if item[1] in [temptool, None]: sublist.append(item[0]) else: sublist.append(item[1]) temptool = item[1] sublist.append(item[0]) postlist.append(sublist) if job.SplitOutput: return postlist else: finalpostlist = [item for slist in postlist for item in slist] return [finalpostlist]
def setDefaultValues(self, obj): """setDefaultValues(obj) ... base implementation. Do not overwrite, overwrite opSetDefaultValues() instead.""" if self.job: job = self.job else: job = PathUtils.addToJob(obj) obj.Active = True features = self.opFeatures(obj) if FeatureTool & features: if 1 < len(job.Operations.Group): obj.ToolController = PathUtil.toolControllerForOp( job.Operations.Group[-2]) else: obj.ToolController = PathUtils.findToolController(obj, self) if not obj.ToolController: raise PathNoTCException() obj.OpToolDiameter = obj.ToolController.Tool.Diameter if FeatureCoolant & features: PathLog.track() PathLog.debug(obj.getEnumerationsOfProperty("CoolantMode")) obj.CoolantMode = job.SetupSheet.CoolantMode if FeatureDepths & features: if self.applyExpression(obj, "StartDepth", job.SetupSheet.StartDepthExpression): obj.OpStartDepth = 1.0 else: obj.StartDepth = 1.0 if self.applyExpression(obj, "FinalDepth", job.SetupSheet.FinalDepthExpression): obj.OpFinalDepth = 0.0 else: obj.FinalDepth = 0.0 else: obj.StartDepth = 1.0 if FeatureStepDown & features: if not self.applyExpression(obj, "StepDown", job.SetupSheet.StepDownExpression): obj.StepDown = "1 mm" if FeatureHeights & features: if job.SetupSheet.SafeHeightExpression: if not self.applyExpression( obj, "SafeHeight", job.SetupSheet.SafeHeightExpression): obj.SafeHeight = "3 mm" if job.SetupSheet.ClearanceHeightExpression: if not self.applyExpression( obj, "ClearanceHeight", job.SetupSheet.ClearanceHeightExpression): obj.ClearanceHeight = "5 mm" if FeatureDiameters & features: obj.MinDiameter = "0 mm" obj.MaxDiameter = "0 mm" if job.Stock: obj.MaxDiameter = job.Stock.Shape.BoundBox.XLength if FeatureStartPoint & features: obj.UseStartPoint = False self.opSetDefaultValues(obj, job) return job