def getFields(self): '''sets properties in the object to match the form''' if self.obj: self.obj.PostProcessor = str(self.form.postProcessor.currentText()) self.obj.PostProcessorArgs = str(self.form.postProcessorArguments.displayText()) self.obj.PostProcessorOutputFile = str(self.form.postProcessorOutputFile.text()) self.obj.Label = str(self.form.jobLabel.text()) self.obj.Description = str(self.form.jobDescription.toPlainText()) self.obj.Operations.Group = [self.form.operationsList.item(i).data(self.DataObject) for i in range(self.form.operationsList.count())] selObj = self.form.jobModel.itemData(self.form.jobModel.currentIndex()) if self.obj.Proxy.baseObject(self.obj) != selObj: self.vproxy.baseObjectRestoreVisibility(self.obj) if PathJob.isResourceClone(self.obj, 'Base'): self.obj.Document.removeObject(self.obj.Base.Name) self.obj.Base = PathJob.createResourceClone(self.obj, selObj, 'Base', 'Base') self.vproxy.baseObjectSaveVisibility(self.obj) self.updateTooltips() self.stockEdit.getFields(self.obj) self.obj.Proxy.execute(self.obj) self.setupGlobal.getFields() self.setupOps.getFields()
def __init__(self, job, parent=None): self.job = job self.dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobTemplateExport.ui") if job.PostProcessor: ppHint = "%s %s %s" % (job.PostProcessor, job.PostProcessorArgs, job.PostProcessorOutputFile) self.dialog.postProcessingHint.setText(ppHint) else: self.dialog.postProcessingGroup.setEnabled(False) self.dialog.postProcessingGroup.setChecked(False) if job.Stock and not PathJob.isResourceClone(job, 'Stock', 'Stock'): if hasattr(job.Stock, 'ExtXNeg'): seHint = translate('PathJob', "Base -/+ %.2f/%.2f %.2f/%.2f %.2f/%.2f") % (job.Stock.ExtXneg, job.Stock.ExtXpos, job.Stock.ExtYneg, job.Stock.ExtYpos, job.Stock.ExtZneg, job.Stock.ExtZpos) self.dialog.stockPlacement.setChecked(False) elif hasattr(job.Stock, 'Length') and hasattr(job.Stock, 'Width'): seHint = translate('PathJob', "Box: %.2f x %.2f x %.2f") % (job.Stock.Length, job.Stock.Width, job.Stock.Height) elif hasattr(job.Stock, 'Radius'): seHint = translate('PathJob', "Cylinder: %.2f x %.2f") % (job.Stock.Radius, job.Stock.Height) else: seHint = '-' PathLog.error(translate('PathJob', 'Unsupported stock type')) self.dialog.stockExtentHint.setText(seHint) spHint = "%s" % job.Stock.Placement self.dialog.stockPlacementHint.setText(spHint) for tc in sorted(job.ToolController, key=lambda o: o.Label): item = QtGui.QListWidgetItem(tc.Label) item.setData(self.DataObject, tc) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.toolsList.addItem(item) self.dialog.toolsGroup.clicked.connect(self.checkUncheckTools)
def updateData(self, obj, prop): PathLog.track(obj.Label, prop) # make sure the resource view providers are setup properly if prop == 'Base' and self.obj.Base and self.obj.Base.ViewObject and self.obj.Base.ViewObject.Proxy: if not PathJob.isArchPanelSheet(self.obj.Base): self.obj.Base.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor) if prop == 'Stock' and self.obj.Stock and self.obj.Stock.ViewObject and self.obj.Stock.ViewObject.Proxy: self.obj.Stock.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor)
def candidates(self, obj): solids = [o for o in obj.Document.Objects if PathUtil.isSolid(o)] if obj.Base in solids and PathJob.isResourceClone(obj, 'Base'): solids.remove(obj.Base) if obj.Stock in solids: # regardless, what stock is/was, it's not a valid choice solids.remove(obj.Stock) return sorted(solids, key=lambda c: c.Label)
def updateData(self, obj, prop): PathLog.track(obj.Label, prop) # make sure the resource view providers are setup properly if prop == 'Base' and self.obj.Base and self.obj.Base.ViewObject and self.obj.Base.ViewObject.Proxy: if not PathJob.isArchPanelSheet(self.obj.Base): self.obj.Base.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor) if prop == 'Stock' and self.obj.Stock and self.obj.Stock.ViewObject and self.obj.Stock.ViewObject.Proxy: self.obj.Stock.ViewObject.Proxy.onEdit(_OpenCloseResourceEditor)
def candidates(self, obj): solids = [o for o in obj.Document.Objects if PathUtil.isSolid(o)] if obj.Base in solids and PathJob.isResourceClone(obj, 'Base'): solids.remove(obj.Base) if obj.Stock in solids: # regardless, what stock is/was, it's not a valid choice solids.remove(obj.Stock) return sorted(solids, key=lambda c: c.Label)
def selection(): '''isActive() ... return True if a dressup command is possible.''' if FreeCAD.ActiveDocument and FreeCAD.GuiUp: import FreeCADGui sel = FreeCADGui.Selection.getSelectionEx() if len(sel) == 1 and sel[0].Object.isDerivedFrom("Path::Feature") and PathJob.Instances(): return sel[0].Object return None
def getFields(self, obj): stock = self.form.stockExisting.itemData(self.form.stockExisting.currentIndex()) if not (hasattr(obj.Stock, 'Objects') and len(obj.Stock.Objects) == 1 and obj.Stock.Objects[0] == stock): if stock: stock = PathJob.createResourceClone(obj, stock, 'Stock', 'Stock') stock.ViewObject.Visibility = True PathStock.SetupStockObject(stock, PathStock.StockType.Unknown) stock.Proxy.execute(stock) self.setStock(obj, stock)
def updateUI(self): job = self.job if job.PostProcessor: ppHint = "%s %s %s" % (job.PostProcessor, job.PostProcessorArgs, job.PostProcessorOutputFile) self.dialog.postProcessingHint.setText(ppHint) else: self.dialog.postProcessingGroup.setEnabled(False) self.dialog.postProcessingGroup.setChecked(False) if job.Stock and not PathJob.isResourceClone(job, 'Stock', 'Stock'): stockType = PathStock.StockType.FromStock(job.Stock) if stockType == PathStock.StockType.FromBase: seHint = translate( 'PathJob', "Base -/+ %.2f/%.2f %.2f/%.2f %.2f/%.2f" ) % (job.Stock.ExtXneg, job.Stock.ExtXpos, job.Stock.ExtYneg, job.Stock.ExtYpos, job.Stock.ExtZneg, job.Stock.ExtZpos) self.dialog.stockPlacement.setChecked(False) elif stockType == PathStock.StockType.CreateBox: seHint = translate('PathJob', "Box: %.2f x %.2f x %.2f") % ( job.Stock.Length, job.Stock.Width, job.Stock.Height) elif stockType == PathStock.StockType.CreateCylinder: seHint = translate('PathJob', "Cylinder: %.2f x %.2f") % ( job.Stock.Radius, job.Stock.Height) else: seHint = '-' PathLog.error(translate('PathJob', 'Unsupported stock type')) self.dialog.stockExtentHint.setText(seHint) spHint = "%s" % job.Stock.Placement self.dialog.stockPlacementHint.setText(spHint) rapidChanged = not job.SetupSheet.Proxy.hasDefaultToolRapids() depthsChanged = not job.SetupSheet.Proxy.hasDefaultOperationDepths() heightsChanged = not job.SetupSheet.Proxy.hasDefaultOperationHeights() coolantChanged = not job.SetupSheet.Proxy.hasDefaultCoolantMode() opsWithSettings = job.SetupSheet.Proxy.operationsWithSettings() settingsChanged = rapidChanged or depthsChanged or heightsChanged or coolantChanged or 0 != len( opsWithSettings) self.dialog.settingsGroup.setChecked(settingsChanged) self.dialog.settingToolRapid.setChecked(rapidChanged) self.dialog.settingOperationDepths.setChecked(depthsChanged) self.dialog.settingOperationHeights.setChecked(heightsChanged) self.dialog.settingCoolant.setChecked(coolantChanged) self.dialog.settingsOpsList.clear() for op in opsWithSettings: item = QtGui.QListWidgetItem(op) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.settingsOpsList.addItem(item) self.dialog.toolsList.clear() for tc in sorted(job.Tools.Group, key=lambda o: o.Label): item = QtGui.QListWidgetItem(tc.Label) item.setData(self.DataObject, tc) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.toolsList.addItem(item)
def test02(self): '''Verify bones are correctly generated for a Profile.''' doc = FreeCAD.newDocument("TestDressupDogbone") # This is a real world test to make sure none of the tool chain broke box0 = doc.addObject('Part::Box', 'Box') box0.Width = 100 box0.Length = 100 box0.Height = 10 box1 = doc.addObject('Part::Box', 'Box') box1.Width = 50 box1.Length = 50 box1.Height = 20 box1.Placement = FreeCAD.Placement(FreeCAD.Vector(25,25,-5), FreeCAD.Rotation(FreeCAD.Vector(0,0,1), 0)) doc.recompute() cut = doc.addObject('Part::Cut', 'Cut') cut.Base = box0 cut.Tool = box1 doc.recompute() for i in range(11): face = "Face%d" % (i+1) f = cut.Shape.getElement(face) if f.Surface.Axis == FreeCAD.Vector(0,0,1) and f.Orientation == 'Forward': break job = PathJob.Create('Job', cut, None) profile = PathProfileFaces.Create('Profile Faces') profile.Base = (cut, face) profile.StepDown = 5 profile.processHoles = True profile.processPerimeter = True doc.recompute() dogbone = PathDressupDogbone.Create(profile) doc.recompute() dog = dogbone.Proxy locs = sorted([bone[1] for bone in dog.bones], key=lambda xy: xy[0] * 1000 + xy[1]) def formatBoneLoc(pt): return "(%.2f, %.2f)" % (pt[0], pt[1]) # Make sure we get 8 bones, 2 in each corner (different heights) self.assertEquals(len(locs), 8) self.assertEquals("(27.50, 27.50)", formatBoneLoc(locs[0])) self.assertEquals("(27.50, 27.50)", formatBoneLoc(locs[1])) self.assertEquals("(27.50, 72.50)", formatBoneLoc(locs[2])) self.assertEquals("(27.50, 72.50)", formatBoneLoc(locs[3])) self.assertEquals("(72.50, 27.50)", formatBoneLoc(locs[4])) self.assertEquals("(72.50, 27.50)", formatBoneLoc(locs[5])) self.assertEquals("(72.50, 72.50)", formatBoneLoc(locs[6])) self.assertEquals("(72.50, 72.50)", formatBoneLoc(locs[7])) FreeCAD.closeDocument("TestDressupDogbone")
def __init__(self, vobj, deleteOnReject): FreeCAD.ActiveDocument.openTransaction( translate("Path_Job", "Edit Job")) self.vobj = vobj self.vproxy = vobj.Proxy self.obj = vobj.Object self.deleteOnReject = deleteOnReject self.form = FreeCADGui.PySideUic.loadUi(":/panels/PathEdit.ui") self.template = PathJobCmd.DlgJobTemplateExport( self.obj, self.form.jobBox.widget(1)) vUnit = FreeCAD.Units.Quantity( 1, FreeCAD.Units.Velocity).getUserPreferred()[2] self.form.toolControllerList.horizontalHeaderItem(1).setText('#') self.form.toolControllerList.horizontalHeaderItem(2).setText(vUnit) self.form.toolControllerList.horizontalHeaderItem(3).setText(vUnit) self.form.toolControllerList.horizontalHeader().setResizeMode( 0, QtGui.QHeaderView.Stretch) self.form.toolControllerList.resizeColumnsToContents() currentPostProcessor = self.obj.PostProcessor postProcessors = PathPreferences.allEnabledPostProcessors( ['', currentPostProcessor]) for post in postProcessors: self.form.postProcessor.addItem(post) # update the enumeration values, just to make sure all selections are valid self.obj.PostProcessor = postProcessors self.obj.PostProcessor = currentPostProcessor base = self.obj.Base if PathJob.isResourceClone(self.obj, 'Base') else None stock = self.obj.Stock for o in PathJob.ObjectJob.baseCandidates(): if o != base and o != stock: self.form.jobModel.addItem(o.Label, o) self.selectComboBoxText(self.form.jobModel, self.obj.Proxy.baseObject(self.obj).Label) self.postProcessorDefaultTooltip = self.form.postProcessor.toolTip() self.postProcessorArgsDefaultTooltip = self.form.postProcessorArguments.toolTip( ) self.vproxy.setupEditVisibility(self.obj) self.stockFromBase = None self.stockFromExisting = None self.stockCreateBox = None self.stockCreateCylinder = None self.stockEdit = None self.setupGlobal = PathSetupSheetGui.GlobalEditor( self.obj.SetupSheet, self.form) self.setupOps = PathSetupSheetGui.OpsDefaultEditor( self.obj.SetupSheet, self.form)
def getFields(self, obj): stock = self.form.stockExisting.itemData( self.form.stockExisting.currentIndex()) if not (hasattr(obj.Stock, 'Objects') and len(obj.Stock.Objects) == 1 and obj.Stock.Objects[0] == stock): if stock: stock = PathJob.createResourceClone(obj, stock, 'Stock', 'Stock') stock.ViewObject.Visibility = True PathStock.SetupStockObject(stock, PathStock.StockType.Unknown) stock.Proxy.execute(stock) self.setStock(obj, stock)
def Create(base, template=None): '''Create(base, template) ... creates a job instance for the given base object using template to configure it.''' FreeCADGui.addModule('PathScripts.PathJob') FreeCAD.ActiveDocument.openTransaction(translate("Path_Job", "Create Job")) try: obj = PathJob.Create('Job', base, template) ViewProvider(obj.ViewObject) FreeCAD.ActiveDocument.commitTransaction() obj.ViewObject.Proxy.editObject(obj.Stock) return obj except: PathLog.error(sys.exc_info()) FreeCAD.ActiveDocument.abortTransaction()
def GetJob(self): # if there's only one Job in the document ... jobs = PathJob.Instances() if not jobs: return None if len(jobs) == 1: return jobs[0] # more than one job, is one of them selected? sel = FreeCADGui.Selection.getSelection() if len(sel) == 1: job = sel[0] if hasattr(job, 'Proxy') and isinstance(job.Proxy, PathJob.ObjectJob): return job return None
def __init__(self, job, parent=None): self.job = job self.dialog = FreeCADGui.PySideUic.loadUi( ":/panels/DlgJobTemplateExport.ui") if job.PostProcessor: ppHint = "%s %s %s" % (job.PostProcessor, job.PostProcessorArgs, job.PostProcessorOutputFile) self.dialog.postProcessingHint.setText(ppHint) else: self.dialog.postProcessingGroup.setEnabled(False) self.dialog.postProcessingGroup.setChecked(False) if job.Stock and not PathJob.isResourceClone(job, 'Stock', 'Stock'): stockType = PathStock.StockType.FromStock(job.Stock) if stockType == PathStock.StockType.FromBase: seHint = translate( 'PathJob', "Base -/+ %.2f/%.2f %.2f/%.2f %.2f/%.2f" ) % (job.Stock.ExtXneg, job.Stock.ExtXpos, job.Stock.ExtYneg, job.Stock.ExtYpos, job.Stock.ExtZneg, job.Stock.ExtZpos) self.dialog.stockPlacement.setChecked(False) elif stockType == PathStock.StockType.CreateBox: seHint = translate('PathJob', "Box: %.2f x %.2f x %.2f") % ( job.Stock.Length, job.Stock.Width, job.Stock.Height) elif stockType == PathStock.StockType.CreateCylinder: seHint = translate('PathJob', "Cylinder: %.2f x %.2f") % ( job.Stock.Radius, job.Stock.Height) else: seHint = '-' PathLog.error(translate('PathJob', 'Unsupported stock type')) self.dialog.stockExtentHint.setText(seHint) spHint = "%s" % job.Stock.Placement self.dialog.stockPlacementHint.setText(spHint) rapidChanged = not job.SetupSheet.Proxy.hasDefaultToolRapids() depthsChanged = not job.SetupSheet.Proxy.hasDefaultOperationDepths() heightsChanged = not job.SetupSheet.Proxy.hasDefaultOperationHeights() settingsChanged = rapidChanged or depthsChanged or heightsChanged self.dialog.settingsGroup.setChecked(settingsChanged) self.dialog.settingToolRapid.setChecked(rapidChanged) self.dialog.settingOperationDepths.setChecked(depthsChanged) self.dialog.settingOperationHeights.setChecked(heightsChanged) for tc in sorted(job.ToolController, key=lambda o: o.Label): item = QtGui.QListWidgetItem(tc.Label) item.setData(self.DataObject, tc) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.toolsList.addItem(item) self.dialog.toolsGroup.clicked.connect(self.checkUncheckTools)
def updateUI(self): job = self.job if job.PostProcessor: ppHint = "%s %s %s" % (job.PostProcessor, job.PostProcessorArgs, job.PostProcessorOutputFile) self.dialog.postProcessingHint.setText(ppHint) else: self.dialog.postProcessingGroup.setEnabled(False) self.dialog.postProcessingGroup.setChecked(False) if job.Stock and not PathJob.isResourceClone(job, 'Stock', 'Stock'): stockType = PathStock.StockType.FromStock(job.Stock) if stockType == PathStock.StockType.FromBase: seHint = translate('PathJob', "Base -/+ %.2f/%.2f %.2f/%.2f %.2f/%.2f") % (job.Stock.ExtXneg, job.Stock.ExtXpos, job.Stock.ExtYneg, job.Stock.ExtYpos, job.Stock.ExtZneg, job.Stock.ExtZpos) self.dialog.stockPlacement.setChecked(False) elif stockType == PathStock.StockType.CreateBox: seHint = translate('PathJob', "Box: %.2f x %.2f x %.2f") % (job.Stock.Length, job.Stock.Width, job.Stock.Height) elif stockType == PathStock.StockType.CreateCylinder: seHint = translate('PathJob', "Cylinder: %.2f x %.2f") % (job.Stock.Radius, job.Stock.Height) else: seHint = '-' PathLog.error(translate('PathJob', 'Unsupported stock type')) self.dialog.stockExtentHint.setText(seHint) spHint = "%s" % job.Stock.Placement self.dialog.stockPlacementHint.setText(spHint) rapidChanged = not job.SetupSheet.Proxy.hasDefaultToolRapids() depthsChanged = not job.SetupSheet.Proxy.hasDefaultOperationDepths() heightsChanged = not job.SetupSheet.Proxy.hasDefaultOperationHeights() opsWithSettings = job.SetupSheet.Proxy.operationsWithSettings() settingsChanged = rapidChanged or depthsChanged or heightsChanged or 0 != len(opsWithSettings) self.dialog.settingsGroup.setChecked(settingsChanged) self.dialog.settingToolRapid.setChecked(rapidChanged) self.dialog.settingOperationDepths.setChecked(depthsChanged) self.dialog.settingOperationHeights.setChecked(heightsChanged) self.dialog.settingsOpsList.clear() for op in opsWithSettings: item = QtGui.QListWidgetItem(op) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.settingsOpsList.addItem(item) self.dialog.toolsList.clear() for tc in sorted(job.ToolController, key=lambda o: o.Label): item = QtGui.QListWidgetItem(tc.Label) item.setData(self.DataObject, tc) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.toolsList.addItem(item)
def __init__(self, vobj, deleteOnReject): FreeCAD.ActiveDocument.openTransaction(translate("Path_Job", "Edit Job")) self.vobj = vobj self.vproxy = vobj.Proxy self.obj = vobj.Object self.deleteOnReject = deleteOnReject self.form = FreeCADGui.PySideUic.loadUi(":/panels/PathEdit.ui") self.template = PathJobCmd.DlgJobTemplateExport(self.obj, self.form.jobBox.widget(1)) vUnit = FreeCAD.Units.Quantity(1, FreeCAD.Units.Velocity).getUserPreferred()[2] self.form.toolControllerList.horizontalHeaderItem(1).setText('#') self.form.toolControllerList.horizontalHeaderItem(2).setText(vUnit) self.form.toolControllerList.horizontalHeaderItem(3).setText(vUnit) self.form.toolControllerList.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Stretch) self.form.toolControllerList.resizeColumnsToContents() currentPostProcessor = self.obj.PostProcessor postProcessors = PathPreferences.allEnabledPostProcessors(['', currentPostProcessor]) for post in postProcessors: self.form.postProcessor.addItem(post) # update the enumeration values, just to make sure all selections are valid self.obj.PostProcessor = postProcessors self.obj.PostProcessor = currentPostProcessor base = self.obj.Base if PathJob.isResourceClone(self.obj, 'Base') else None stock = self.obj.Stock for o in PathJob.ObjectJob.baseCandidates(): if o != base and o != stock: self.form.jobModel.addItem(o.Label, o) self.selectComboBoxText(self.form.jobModel, self.obj.Proxy.baseObject(self.obj).Label) self.postProcessorDefaultTooltip = self.form.postProcessor.toolTip() self.postProcessorArgsDefaultTooltip = self.form.postProcessorArguments.toolTip() self.vproxy.setupEditVisibility(self.obj) self.stockFromBase = None self.stockFromExisting = None self.stockCreateBox = None self.stockCreateCylinder = None self.stockEdit = None self.setupGlobal = PathSetupSheetGui.GlobalEditor(self.obj.SetupSheet, self.form) self.setupOps = PathSetupSheetGui.OpsDefaultEditor(self.obj.SetupSheet, self.form)
def __init__(self, job, parent=None): self.job = job self.dialog = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobTemplateExport.ui") if job.PostProcessor: ppHint = "%s %s %s" % (job.PostProcessor, job.PostProcessorArgs, job.PostProcessorOutputFile) self.dialog.postProcessingHint.setText(ppHint) else: self.dialog.postProcessingGroup.setEnabled(False) self.dialog.postProcessingGroup.setChecked(False) if job.Stock and not PathJob.isResourceClone(job, 'Stock', 'Stock'): stockType = PathStock.StockType.FromStock(job.Stock) if stockType == PathStock.StockType.FromBase: seHint = translate('PathJob', "Base -/+ %.2f/%.2f %.2f/%.2f %.2f/%.2f") % (job.Stock.ExtXneg, job.Stock.ExtXpos, job.Stock.ExtYneg, job.Stock.ExtYpos, job.Stock.ExtZneg, job.Stock.ExtZpos) self.dialog.stockPlacement.setChecked(False) elif stockType == PathStock.StockType.CreateBox: seHint = translate('PathJob', "Box: %.2f x %.2f x %.2f") % (job.Stock.Length, job.Stock.Width, job.Stock.Height) elif stockType == PathStock.StockType.CreateCylinder: seHint = translate('PathJob', "Cylinder: %.2f x %.2f") % (job.Stock.Radius, job.Stock.Height) else: seHint = '-' PathLog.error(translate('PathJob', 'Unsupported stock type')) self.dialog.stockExtentHint.setText(seHint) spHint = "%s" % job.Stock.Placement self.dialog.stockPlacementHint.setText(spHint) rapidChanged = not job.SetupSheet.Proxy.hasDefaultToolRapids() depthsChanged = not job.SetupSheet.Proxy.hasDefaultOperationDepths() heightsChanged = not job.SetupSheet.Proxy.hasDefaultOperationHeights() settingsChanged = rapidChanged or depthsChanged or heightsChanged self.dialog.settingsGroup.setChecked(settingsChanged) self.dialog.settingToolRapid.setChecked(rapidChanged) self.dialog.settingOperationDepths.setChecked(depthsChanged) self.dialog.settingOperationHeights.setChecked(heightsChanged) for tc in sorted(job.ToolController, key=lambda o: o.Label): item = QtGui.QListWidgetItem(tc.Label) item.setData(self.DataObject, tc) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.toolsList.addItem(item) self.dialog.toolsGroup.clicked.connect(self.checkUncheckTools)
def test03(self): '''Verify Helix generates proper holes for rotated base model''' for deg in range(self.RotateBy, 360, self.RotateBy): self.tearDown() self.doc = FreeCAD.open(FreeCAD.getHomePath() + 'Mod/Path/PathTests/test_holes00.fcstd') self.doc.Body.Placement.Rotation = FreeCAD.Rotation(deg, 0, 0) self.job = PathJob.Create('Job', [self.doc.Body]) self.job.ToolController[0].Tool.Diameter = 0.5 op = PathHelix.Create('Helix') proxy = op.Proxy model = self.job.Model.Group[0] for base in op.Base: model = base[0] for sub in base[1]: pos = proxy.holePosition(op, model, sub) #PathLog.track(deg, pos, pos.Length) self.assertRoughly(round(pos.Length / 10, 0), proxy.holeDiameter(op, model, sub))
def __init__(self, job, parent=None): self.job = job self.dialog = FreeCADGui.PySideUic.loadUi( ":/panels/DlgJobTemplateExport.ui") if job.PostProcessor: ppHint = "%s %s %s" % (job.PostProcessor, job.PostProcessorArgs, job.PostProcessorOutputFile) self.dialog.postProcessingHint.setText(ppHint) else: self.dialog.postProcessingGroup.setEnabled(False) self.dialog.postProcessingGroup.setChecked(False) if job.Stock and not PathJob.isResourceClone(job, 'Stock', 'Stock'): if hasattr(job.Stock, 'ExtXNeg'): seHint = translate( 'PathJob', "Base -/+ %.2f/%.2f %.2f/%.2f %.2f/%.2f" ) % (job.Stock.ExtXneg, job.Stock.ExtXpos, job.Stock.ExtYneg, job.Stock.ExtYpos, job.Stock.ExtZneg, job.Stock.ExtZpos) self.dialog.stockPlacement.setChecked(False) elif hasattr(job.Stock, 'Length') and hasattr(job.Stock, 'Width'): seHint = translate('PathJob', "Box: %.2f x %.2f x %.2f") % ( job.Stock.Length, job.Stock.Width, job.Stock.Height) elif hasattr(job.Stock, 'Radius'): seHint = translate('PathJob', "Cylinder: %.2f x %.2f") % ( job.Stock.Radius, job.Stock.Height) else: seHint = '-' PathLog.error(translate('PathJob', 'Unsupported stock type')) self.dialog.stockExtentHint.setText(seHint) spHint = "%s" % job.Stock.Placement self.dialog.stockPlacementHint.setText(spHint) for tc in sorted(job.ToolController, key=lambda o: o.Label): item = QtGui.QListWidgetItem(tc.Label) item.setData(self.DataObject, tc) item.setCheckState(QtCore.Qt.CheckState.Checked) self.dialog.toolsList.addItem(item) self.dialog.toolsGroup.clicked.connect(self.checkUncheckTools)
def test003(self, close=True): """test003()... Verify 'No job object' exception thrown if Job object available.""" from PathScripts.post import gcode_pre as gcode_pre doc = FreeCAD.newDocument("TestPathPost") # Add temporary receiving Job object box = FreeCAD.ActiveDocument.addObject("Part::Box", "Box") box.Label = "Temporary Box" # Add Job object with view provider support when possible if FreeCAD.GuiUp: import PathScripts.PathJobGui as PathJobGui box.ViewObject.Visibility = False job = PathJobGui.Create([box], openTaskPanel=False) else: import PathScripts.PathJob as PathJob job = PathJob.Create("Job", [box]) importFile = FreeCAD.getHomePath( ) + "Mod/Path/PathTests/test_centroid_00.ngc" gcode_pre.insert(importFile, "test_centroid_00") # self.assertTrue(doc.Name == "test_centroid_00") opList = doc.Job.Operations.Group self.assertTrue( len(opList) == 2, "Expected 2 Custom operations to be created from source g-code file, test_centroid_00.ngc", ) self.assertTrue(opList[0].Name == "Custom", "Expected first operation to be Custom") self.assertTrue(opList[1].Name == "Custom001", "Expected second operation to be Custom001") if close: FreeCAD.closeDocument(doc.Name)
def test04(self): """Verify Helix generates proper holes for rotated clone base model""" for deg in range(self.RotateBy, 360, self.RotateBy): self.tearDown() self.doc = FreeCAD.open(FreeCAD.getHomePath() + "Mod/Path/PathTests/test_holes00.fcstd") self.clone = Draft.clone(self.doc.Body) self.clone.Placement.Rotation = FreeCAD.Rotation(deg, 0, 0) self.job = PathJob.Create("Job", [self.clone]) self.job.Tools.Group[0].Tool.Diameter = 0.5 op = PathHelix.Create("Helix") proxy = op.Proxy model = self.job.Model.Group[0] for base in op.Base: model = base[0] for sub in base[1]: pos = proxy.holePosition(op, model, sub) # PathLog.track(deg, pos, pos.Length) self.assertRoughly(round(pos.Length / 10, 0), proxy.holeDiameter(op, model, sub))
def GetJobs(jobname=None): '''returns all jobs in the current document. If name is given, returns that job''' if jobname: return [job for job in PathJob.Instances() if job.Name == jobname] return PathJob.Instances()
def setupModel(self, job=None): if job: preSelected = Counter([ PathUtil.getPublicObject(job.Proxy.baseObject(job, obj)).Label for obj in job.Model.Group ]) jobResources = job.Model.Group + [job.Stock] else: preSelected = Counter( [obj.Label for obj in FreeCADGui.Selection.getSelection()]) jobResources = [] self.candidates = sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label) # If there is only one possibility we might as well make sure it's selected if not preSelected and 1 == len(self.candidates): preSelected = Counter([self.candidates[0].Label]) expandSolids = False expand2Ds = False expandJobs = False for base in self.candidates: if (not base in jobResources and not PathJob.isResourceClone(job, base, None) and not hasattr(base, "StockType")): item0 = QtGui.QStandardItem() item1 = QtGui.QStandardItem() item0.setData(base.Label, QtCore.Qt.EditRole) item0.setData(base, self.DataObject) item0.setCheckable(True) item0.setEditable(False) item1.setEnabled(True) item1.setEditable(True) if base.Label in preSelected: itemSelected = True item0.setCheckState(QtCore.Qt.CheckState.Checked) item1.setData(preSelected[base.Label], QtCore.Qt.EditRole) else: itemSelected = False item0.setCheckState(QtCore.Qt.CheckState.Unchecked) item1.setData(0, QtCore.Qt.EditRole) if PathUtil.isSolid(base): self.itemsSolid.appendRow([item0, item1]) if itemSelected: expandSolids = True else: self.items2D.appendRow([item0, item1]) if itemSelected: expand2Ds = True for j in sorted(PathJob.Instances(), key=lambda x: x.Label): if j != job: item0 = QtGui.QStandardItem() item1 = QtGui.QStandardItem() item0.setData(j.Label, QtCore.Qt.EditRole) item0.setData(j, self.DataObject) item0.setCheckable(True) item0.setEditable(False) item1.setEnabled(True) item1.setEditable(True) if j.Label in preSelected: expandJobs = True item0.setCheckState(QtCore.Qt.CheckState.Checked) item1.setData(preSelected[j.Label], QtCore.Qt.EditRole) else: item0.setCheckState(QtCore.Qt.CheckState.Unchecked) item1.setData(0, QtCore.Qt.EditRole) self.itemsJob.appendRow([item0, item1]) self.delegate = _ItemDelegate(self, self.dialog.modelTree) self.model = QtGui.QStandardItemModel(self.dialog) self.model.setHorizontalHeaderLabels(["Model", "Count"]) if self.itemsSolid.hasChildren(): self.model.appendRow(self.itemsSolid) if expandSolids or not (expand2Ds or expandJobs): expandSolids = True if self.items2D.hasChildren(): self.model.appendRow(self.items2D) if self.itemsJob.hasChildren(): self.model.appendRow(self.itemsJob) self.dialog.modelTree.setModel(self.model) self.dialog.modelTree.setItemDelegateForColumn(1, self.delegate) self.dialog.modelTree.expandAll() self.dialog.modelTree.resizeColumnToContents(0) self.dialog.modelTree.resizeColumnToContents(1) self.dialog.modelTree.collapseAll() if expandSolids: self.dialog.modelTree.setExpanded(self.itemsSolid.index(), True) if expand2Ds: self.dialog.modelTree.setExpanded(self.items2D.index(), True) if expandJobs: self.dialog.modelTree.setExpanded(self.itemsJob.index(), True) self.dialog.modelTree.setEditTriggers( QtGui.QAbstractItemView.AllEditTriggers) self.dialog.modelTree.setSelectionBehavior( QtGui.QAbstractItemView.SelectItems) self.dialog.modelGroup.show()
def setUp(self): self.clone = None self.doc = FreeCAD.open(FreeCAD.getHomePath() + 'Mod/Path/PathTests/test_holes00.fcstd') self.job = PathJob.Create('Job', [self.doc.Body])
def setupModel(self, job = None): if job: preSelected = Counter([PathUtil.getPublicObject(job.Proxy.baseObject(job, obj)).Label for obj in job.Model.Group]) jobResources = job.Model.Group + [job.Stock] else: preSelected = Counter([obj.Label for obj in FreeCADGui.Selection.getSelection()]) jobResources = [] self.candidates = sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label) # If there is only one possibility we might as well make sure it's selected if not preSelected and 1 == len(self.candidates): preSelected = Counter([self.candidates[0].Label]) expandSolids = False expand2Ds = False expandJobs = False for i, base in enumerate(self.candidates): if not base in jobResources and not PathJob.isResourceClone(job, base, None) and not hasattr(base, 'StockType'): item0 = QtGui.QStandardItem() item1 = QtGui.QStandardItem() item0.setData(base.Label, QtCore.Qt.EditRole) item0.setData(base, self.DataObject) item0.setCheckable(True) item0.setEditable(False) item1.setEnabled(True) item1.setEditable(True) if base.Label in preSelected: itemSelected = True item0.setCheckState(QtCore.Qt.CheckState.Checked) item1.setData(preSelected[base.Label], QtCore.Qt.EditRole) else: itemSelected = False item0.setCheckState(QtCore.Qt.CheckState.Unchecked) item1.setData(0, QtCore.Qt.EditRole) if PathUtil.isSolid(base): self.itemsSolid.appendRow([item0, item1]) if itemSelected: expandSolids = True else: self.items2D.appendRow([item0, item1]) if itemSelected: expand2Ds = True for j in sorted(PathJob.Instances(), key=lambda x: x.Label): if j != job: item0 = QtGui.QStandardItem() item1 = QtGui.QStandardItem() item0.setData(j.Label, QtCore.Qt.EditRole) item0.setData(j, self.DataObject) item0.setCheckable(True) item0.setEditable(False) item1.setEnabled(True) item1.setEditable(True) if j.Label in preSelected: expandJobs = True item0.setCheckState(QtCore.Qt.CheckState.Checked) item1.setData(preSelected[j.Label], QtCore.Qt.EditRole) else: item0.setCheckState(QtCore.Qt.CheckState.Unchecked) item1.setData(0, QtCore.Qt.EditRole) self.itemsJob.appendRow([item0, item1]) self.delegate = _ItemDelegate(self, self.dialog.modelTree) self.model = QtGui.QStandardItemModel(self.dialog) self.model.setHorizontalHeaderLabels(['Model', 'Count']) if self.itemsSolid.hasChildren(): self.model.appendRow(self.itemsSolid) if expandSolids or not (expand2Ds or expandJobs): expandSolids = True if self.items2D.hasChildren(): self.model.appendRow(self.items2D) if self.itemsJob.hasChildren(): self.model.appendRow(self.itemsJob) self.dialog.modelTree.setModel(self.model) self.dialog.modelTree.setItemDelegateForColumn(1, self.delegate) self.dialog.modelTree.expandAll() self.dialog.modelTree.resizeColumnToContents(0) self.dialog.modelTree.resizeColumnToContents(1) self.dialog.modelTree.collapseAll() if expandSolids: self.dialog.modelTree.setExpanded(self.itemsSolid.index(), True) if expand2Ds: self.dialog.modelTree.setExpanded(self.items2D.index(), True) if expandJobs: self.dialog.modelTree.setExpanded(self.itemsJob.index(), True) self.dialog.modelTree.setEditTriggers(QtGui.QAbstractItemView.AllEditTriggers) self.dialog.modelTree.setSelectionBehavior(QtGui.QAbstractItemView.SelectItems) self.dialog.modelGroup.show()
def test02(self): '''Verify bones are correctly generated for a Profile.''' doc = FreeCAD.newDocument("TestDressupDogbone") # This is a real world test to make sure none of the tool chain broke box0 = doc.addObject('Part::Box', 'Box') box0.Width = 100 box0.Length = 100 box0.Height = 10 box1 = doc.addObject('Part::Box', 'Box') box1.Width = 50 box1.Length = 50 box1.Height = 20 box1.Placement = FreeCAD.Placement( FreeCAD.Vector(25, 25, -5), FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1), 0)) doc.recompute() cut = doc.addObject('Part::Cut', 'Cut') cut.Base = box0 cut.Tool = box1 doc.recompute() for i in range(11): face = "Face%d" % (i + 1) f = cut.Shape.getElement(face) if f.Surface.Axis == FreeCAD.Vector( 0, 0, 1) and f.Orientation == 'Forward': break PathJob.Create('Job', [cut], None) profile = PathProfileFaces.Create('Profile Faces') profile.Base = (cut, face) profile.StepDown = 5 # set start and final depth in order to eliminate effects of stock (and its default values) profile.setExpression('StartDepth', None) profile.StartDepth = 10 profile.setExpression('FinalDepth', None) profile.FinalDepth = 0 profile.processHoles = True profile.processPerimeter = True doc.recompute() dogbone = PathDressupDogbone.Create(profile) doc.recompute() dog = dogbone.Proxy locs = sorted([bone[1] for bone in dog.bones], key=lambda xy: xy[0] * 1000 + xy[1]) def formatBoneLoc(pt): return "(%.2f, %.2f)" % (pt[0], pt[1]) # Make sure we get 8 bones, 2 in each corner (different heights) # with start point changes it passes back over the same spot multiple times, so just make sure they are in the right locations # self.assertEqual(len(locs), 8) self.assertEqual("(27.50, 27.50)", formatBoneLoc(locs[0])) self.assertEqual("(27.50, 27.50)", formatBoneLoc(locs[1])) self.assertEqual("(27.50, 72.50)", formatBoneLoc(locs[2])) self.assertEqual("(27.50, 72.50)", formatBoneLoc(locs[3])) self.assertEqual("(72.50, 27.50)", formatBoneLoc(locs[4])) self.assertEqual("(72.50, 27.50)", formatBoneLoc(locs[5])) self.assertEqual("(72.50, 72.50)", formatBoneLoc(locs[6])) self.assertEqual("(72.50, 72.50)", formatBoneLoc(locs[7])) FreeCAD.closeDocument("TestDressupDogbone")
def setupModel(self, job=None): if job: sel = [ PathUtil.getPublicObject(job.Proxy.baseObject(job, obj)) for obj in job.Model.Group ] xxx = job.Model.Group + [job.Stock] else: sel = FreeCADGui.Selection.getSelection() xxx = [] if sel: selected = [s.Label for s in sel] else: selected = [] PathLog.track('selected', selected) expandSolids = False expandTwoDs = False expandJobs = False index = 0 candidates = sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label) for base in candidates: PathLog.track(base.Label) if not base in xxx and not PathJob.isResourceClone( job, base, None) and not hasattr(base, 'StockType'): PathLog.track('base', base.Label) item = QtGui.QTreeWidgetItem([base.Label]) item.setData(0, self.DataObject, base) sel = base.Label in selected if sel or (1 == len(candidates) and not selected): item.setCheckState(0, QtCore.Qt.CheckState.Checked) else: item.setCheckState(0, QtCore.Qt.CheckState.Unchecked) if PathUtil.isSolid(base): self.itemsSolid.addChild(item) if sel: expandSolids = True else: self.itemsTwoD.addChild(item) if sel: expandTwoDs = True for j in sorted(PathJob.Instances(), key=lambda x: x.Label): if j != job: item = QtGui.QTreeWidgetItem([j.Label]) item.setData(0, self.DataObject, j) if j.Label in selected: expandJobs = True item.setCheckState(0, QtCore.Qt.CheckState.Checked) else: item.setCheckState(0, QtCore.Qt.CheckState.Unchecked) self.itemsJob.addChild(item) if self.itemsSolid.childCount() > 0: self.dialog.modelTree.addTopLevelItem(self.itemsSolid) if expandSolids or not (expandTwoDs or expandJobs): PathLog.track() self.itemsSolid.setExpanded(True) expandSolids = True if self.itemsTwoD.childCount() > 0: self.dialog.modelTree.addTopLevelItem(self.itemsTwoD) if expandTwoDs: self.itemsTwoD.setExpanded(True) if self.itemsJob.childCount() > 0: self.dialog.modelTree.addTopLevelItem(self.itemsJob) if expandJobs: self.itemsJob.setExpanded(True) self.dialog.modelGroup.show()
def setupModel(self, job = None): if job: sel = [PathUtil.getPublicObject(job.Proxy.baseObject(job, obj)) for obj in job.Model.Group] xxx = job.Model.Group + [job.Stock] else: sel = FreeCADGui.Selection.getSelection() xxx = [] if sel: selected = [s.Label for s in sel] else: selected = [] PathLog.track('selected', selected) expandSolids = False expandTwoDs = False expandJobs = False index = 0 candidates = sorted(PathJob.ObjectJob.baseCandidates(), key=lambda o: o.Label) for base in candidates: PathLog.track(base.Label) if not base in xxx and not PathJob.isResourceClone(job, base, None) and not hasattr(base, 'StockType'): PathLog.track('base', base.Label) item = QtGui.QTreeWidgetItem([base.Label]) item.setData(0, self.DataObject, base) sel = base.Label in selected if sel or (1 == len(candidates) and not selected): item.setCheckState(0, QtCore.Qt.CheckState.Checked) else: item.setCheckState(0, QtCore.Qt.CheckState.Unchecked) if PathUtil.isSolid(base): self.itemsSolid.addChild(item) if sel: expandSolids = True else: self.itemsTwoD.addChild(item) if sel: expandTwoDs = True for j in sorted(PathJob.Instances(), key=lambda x: x.Label): if j != job: item = QtGui.QTreeWidgetItem([j.Label]) item.setData(0, self.DataObject, j) if j.Label in selected: expandJobs = True item.setCheckState(0, QtCore.Qt.CheckState.Checked) else: item.setCheckState(0, QtCore.Qt.CheckState.Unchecked) self.itemsJob.addChild(item) if self.itemsSolid.childCount() > 0: self.dialog.modelTree.addTopLevelItem(self.itemsSolid) if expandSolids or not (expandTwoDs or expandJobs): PathLog.track() self.itemsSolid.setExpanded(True) expandSolids = True if self.itemsTwoD.childCount() > 0: self.dialog.modelTree.addTopLevelItem(self.itemsTwoD) if expandTwoDs: self.itemsTwoD.setExpanded(True) if self.itemsJob.childCount() > 0: self.dialog.modelTree.addTopLevelItem(self.itemsJob) if expandJobs: self.itemsJob.setExpanded(True) self.dialog.modelGroup.show()