def initOperation(self, obj): """initOperation(obj) ... create vcarve specific properties.""" obj.addProperty( "App::PropertyFloat", "Discretize", "Path", QT_TRANSLATE_NOOP("App::Property", "The deflection value for discretizing arcs"), ) obj.addProperty( "App::PropertyFloat", "Colinear", "Path", QT_TRANSLATE_NOOP( "App::Property", "Cutoff for removing colinear segments (degrees). \ default=10.0.", ), ) obj.addProperty( "App::PropertyFloat", "Tolerance", "Path", QT_TRANSLATE_NOOP("App::Property", "Vcarve Tolerance"), ) obj.Colinear = 10.0 obj.Discretize = 0.01 obj.Tolerance = PathPreferences.defaultGeometryTolerance() self.setupAdditionalProperties(obj)
def opExecute(self, obj): '''opExecute(obj) ... process engraving operation''' PathLog.track() output = "" if obj.Comment != "": output += '(' + str(obj.Comment) + ')\n' output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str( obj.ToolController.Tool.Diameter) + ")" parentJob = PathUtils.findParentJob(obj) if parentJob is None: return print("base object: " + self.baseobject.Name) if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']: try: import ocl except: FreeCAD.Console.PrintError( translate( "Path_Surface", "This operation requires OpenCamLib to be installed.") + "\n") return if self.baseobject.TypeId.startswith('Mesh'): mesh = self.baseobject.Mesh else: # try/except is for Path Jobs created before GeometryTolerance try: deflection = parentJob.GeometryTolerance except AttributeError: import PathScripts.PathPreferences as PathPreferences deflection = PathPreferences.defaultGeometryTolerance() self.baseobject.Shape.tessellate(0.5) mesh = MeshPart.meshFromShape(self.baseobject.Shape, Deflection=deflection) bb = mesh.BoundBox s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point(q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2])) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) self.commandlist.extend(output)
def loadSettings(self): self.form.leDefaultFilePath.setText(PathPreferences.defaultFilePath()) self.form.leDefaultJobTemplate.setText(PathPreferences.defaultJobTemplate()) blacklist = PathPreferences.postProcessorBlacklist() for processor in PathPreferences.allAvailablePostProcessors(): item = QtGui.QListWidgetItem(processor) if processor in blacklist: item.setCheckState(QtCore.Qt.CheckState.Unchecked) else: item.setCheckState(QtCore.Qt.CheckState.Checked) item.setFlags( QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled | QtCore.Qt.ItemFlag.ItemIsUserCheckable) self.form.postProcessorList.addItem(item) self.verifyAndUpdateDefaultPostProcessorWith(PathPreferences.defaultPostProcessor()) self.form.defaultPostProcessorArgs.setText(PathPreferences.defaultPostProcessorArgs()) geomTol = Units.Quantity(PathPreferences.defaultGeometryTolerance(), Units.Length) self.form.geometryTolerance.setText(geomTol.UserString) self.form.curveAccuracy.setText(Units.Quantity(PathPreferences.defaultLibAreaCurveAccuracy(), Units.Length).UserString) self.form.leOutputFile.setText(PathPreferences.defaultOutputFile()) self.selectComboEntry(self.form.cboOutputPolicy, PathPreferences.defaultOutputPolicy()) self.form.tbDefaultFilePath.clicked.connect(self.browseDefaultFilePath) self.form.tbDefaultJobTemplate.clicked.connect(self.browseDefaultJobTemplate) self.form.postProcessorList.itemEntered.connect(self.setProcessorListTooltip) self.form.postProcessorList.itemChanged.connect(self.verifyAndUpdateDefaultPostProcessor) self.form.defaultPostProcessor.currentIndexChanged.connect(self.updateDefaultPostProcessorToolTip) self.form.tbOutputFile.clicked.connect(self.browseOutputFile) self.loadStockSettings()
def __init__(self, obj, models, templateFile = None): self.obj = obj obj.addProperty("App::PropertyFile", "PostProcessorOutputFile", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob","The NC output file for this project")) obj.addProperty("App::PropertyEnumeration", "PostProcessor", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob","Select the Post Processor")) obj.addProperty("App::PropertyString", "PostProcessorArgs", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Arguments for the Post Processor (specific to the script)")) obj.addProperty("App::PropertyString", "Description", "Path", QtCore.QT_TRANSLATE_NOOP("PathJob","An optional description for this job")) obj.addProperty("App::PropertyString", "CycleTime", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Operations Cycle Time Estimation")) obj.setEditorMode('CycleTime', 1) # read-only obj.addProperty("App::PropertyDistance", "GeometryTolerance", "Geometry", QtCore.QT_TRANSLATE_NOOP("PathJob", "For computing Paths; smaller increases accuracy, but slows down computation")) obj.addProperty("App::PropertyLink", "Stock", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Solid object to be used as stock.")) obj.addProperty("App::PropertyLink", "Operations", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Compound path of all operations in the order they are processed.")) obj.addProperty("App::PropertyLinkList", "ToolController", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Collection of tool controllers available for this job.")) obj.addProperty("App::PropertyBool", "SplitOutput", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob","Split output into multiple gcode files")) obj.addProperty("App::PropertyEnumeration", "OrderOutputBy", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "If multiple WCS, order the output this way")) obj.addProperty("App::PropertyStringList", "Fixtures", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "The Work Coordinate Systems for the Job")) obj.OrderOutputBy = ['Fixture', 'Tool', 'Operation'] obj.Fixtures = ['G54'] obj.PostProcessorOutputFile = PathPreferences.defaultOutputFile() #obj.setEditorMode("PostProcessorOutputFile", 0) # set to default mode obj.PostProcessor = postProcessors = PathPreferences.allEnabledPostProcessors() defaultPostProcessor = PathPreferences.defaultPostProcessor() # Check to see if default post processor hasn't been 'lost' (This can happen when Macro dir has changed) if defaultPostProcessor in postProcessors: obj.PostProcessor = defaultPostProcessor else: obj.PostProcessor = postProcessors[0] obj.PostProcessorArgs = PathPreferences.defaultPostProcessorArgs() obj.GeometryTolerance = PathPreferences.defaultGeometryTolerance() ops = FreeCAD.ActiveDocument.addObject("Path::FeatureCompoundPython", "Operations") if ops.ViewObject: ops.ViewObject.Proxy = 0 ops.ViewObject.Visibility = False obj.Operations = ops obj.setEditorMode('Operations', 2) # hide obj.setEditorMode('Placement', 2) self.setupSetupSheet(obj) self.setupBaseModel(obj, models) self.tooltip = None self.tooltipArgs = None obj.Proxy = self self.setFromTemplateFile(obj, templateFile) if not obj.Stock: stockTemplate = PathPreferences.defaultStockTemplate() if stockTemplate: obj.Stock = PathStock.CreateFromTemplate(obj, json.loads(stockTemplate)) if not obj.Stock: obj.Stock = PathStock.CreateFromBase(obj) if obj.Stock.ViewObject: obj.Stock.ViewObject.Visibility = False
def __init__(self, obj, models, templateFile = None): self.obj = obj obj.addProperty("App::PropertyFile", "PostProcessorOutputFile", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob","The NC output file for this project")) obj.addProperty("App::PropertyEnumeration", "PostProcessor", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob","Select the Post Processor")) obj.addProperty("App::PropertyString", "PostProcessorArgs", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob", "Arguments for the Post Processor (specific to the script)")) obj.addProperty("App::PropertyString", "Description", "Path", QtCore.QT_TRANSLATE_NOOP("PathJob","An optional description for this job")) obj.addProperty("App::PropertyDistance", "GeometryTolerance", "Geometry", QtCore.QT_TRANSLATE_NOOP("PathJob", "For computing Paths; smaller increases accuracy, but slows down computation")) obj.addProperty("App::PropertyLink", "Stock", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Solid object to be used as stock.")) obj.addProperty("App::PropertyLink", "Operations", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Compound path of all operations in the order they are processed.")) obj.addProperty("App::PropertyLinkList", "ToolController", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Collection of tool controllers available for this job.")) obj.addProperty("App::PropertyBool", "SplitOutput", "Output", QtCore.QT_TRANSLATE_NOOP("PathJob","Split output into multiple gcode files")) obj.addProperty("App::PropertyEnumeration", "OrderOutputBy", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "If multiple WCS, order the output this way")) obj.addProperty("App::PropertyStringList", "Fixtures", "WCS", QtCore.QT_TRANSLATE_NOOP("PathJob", "The Work Coordinate Systems for the Job")) obj.OrderOutputBy = ['Fixture', 'Tool', 'Operation'] obj.Fixtures = ['G54'] obj.PostProcessorOutputFile = PathPreferences.defaultOutputFile() #obj.setEditorMode("PostProcessorOutputFile", 0) # set to default mode obj.PostProcessor = postProcessors = PathPreferences.allEnabledPostProcessors() defaultPostProcessor = PathPreferences.defaultPostProcessor() # Check to see if default post processor hasn't been 'lost' (This can happen when Macro dir has changed) if defaultPostProcessor in postProcessors: obj.PostProcessor = defaultPostProcessor else: obj.PostProcessor = postProcessors[0] obj.PostProcessorArgs = PathPreferences.defaultPostProcessorArgs() obj.GeometryTolerance = PathPreferences.defaultGeometryTolerance() ops = FreeCAD.ActiveDocument.addObject("Path::FeatureCompoundPython", "Operations") if ops.ViewObject: ops.ViewObject.Proxy = 0 ops.ViewObject.Visibility = False obj.Operations = ops obj.setEditorMode('Operations', 2) # hide obj.setEditorMode('Placement', 2) self.setupSetupSheet(obj) self.setupBaseModel(obj, models) obj.Proxy = self self.setFromTemplateFile(obj, templateFile) if not obj.Stock: stockTemplate = PathPreferences.defaultStockTemplate() if stockTemplate: obj.Stock = PathStock.CreateFromTemplate(obj, json.loads(stockTemplate)) if not obj.Stock: obj.Stock = PathStock.CreateFromBase(obj) if obj.Stock.ViewObject: obj.Stock.ViewObject.Visibility = False
def initOperation(self, obj): '''initOperation(obj) ... create vcarve specific properties.''' obj.addProperty("App::PropertyFloat", "Discretize", "Path", QtCore.QT_TRANSLATE_NOOP("PathVcarve", "The deflection value for discretizing arcs")) obj.addProperty("App::PropertyFloat", "Threshold", "Path", QtCore.QT_TRANSLATE_NOOP("PathVcarve", "cutoff for removing colinear segments (degrees). \ default=10.0.")) obj.addProperty("App::PropertyFloat", "Tolerance", "Path", QtCore.QT_TRANSLATE_NOOP("PathVcarve", "")) obj.Threshold = 10.0 obj.Discretize = 0.01 obj.Tolerance = PathPreferences.defaultGeometryTolerance() self.setupAdditionalProperties(obj)
def __init__(self, obj, models, templateFile=None): self.obj = obj self.tooltip = None self.tooltipArgs = None obj.Proxy = self obj.addProperty( "App::PropertyFile", "PostProcessorOutputFile", "Output", QT_TRANSLATE_NOOP("App::Property", "The NC output file for this project"), ) obj.addProperty( "App::PropertyEnumeration", "PostProcessor", "Output", QT_TRANSLATE_NOOP("App::Property", "Select the Post Processor"), ) obj.addProperty( "App::PropertyString", "PostProcessorArgs", "Output", QT_TRANSLATE_NOOP( "App::Property", "Arguments for the Post Processor (specific to the script)", ), ) obj.addProperty( "App::PropertyString", "LastPostProcessDate", "Output", QT_TRANSLATE_NOOP("App::Property", "Last Time the Job was post-processed"), ) obj.setEditorMode("LastPostProcessDate", 2) # Hide obj.addProperty( "App::PropertyString", "LastPostProcessOutput", "Output", QT_TRANSLATE_NOOP("App::Property", "Last Time the Job was post-processed"), ) obj.setEditorMode("LastPostProcessOutput", 2) # Hide obj.addProperty( "App::PropertyString", "Description", "Path", QT_TRANSLATE_NOOP("App::Property", "An optional description for this job"), ) obj.addProperty( "App::PropertyString", "CycleTime", "Path", QT_TRANSLATE_NOOP("App::Property", "Job Cycle Time Estimation"), ) obj.setEditorMode("CycleTime", 1) # read-only obj.addProperty( "App::PropertyDistance", "GeometryTolerance", "Geometry", QT_TRANSLATE_NOOP( "App::Property", "For computing Paths; smaller increases accuracy, but slows down computation", ), ) obj.addProperty( "App::PropertyLink", "Stock", "Base", QT_TRANSLATE_NOOP("App::Property", "Solid object to be used as stock."), ) obj.addProperty( "App::PropertyLink", "Operations", "Base", QT_TRANSLATE_NOOP( "App::Property", "Compound path of all operations in the order they are processed.", ), ) obj.addProperty( "App::PropertyEnumeration", "JobType", "Base", QT_TRANSLATE_NOOP("App::Property", "Select the Type of Job"), ) obj.setEditorMode("JobType", 2) # Hide obj.addProperty( "App::PropertyBool", "SplitOutput", "Output", QT_TRANSLATE_NOOP("App::Property", "Split output into multiple gcode files"), ) obj.addProperty( "App::PropertyEnumeration", "OrderOutputBy", "WCS", QT_TRANSLATE_NOOP("App::Property", "If multiple WCS, order the output this way"), ) obj.addProperty( "App::PropertyStringList", "Fixtures", "WCS", QT_TRANSLATE_NOOP("App::Property", "The Work Coordinate Systems for the Job"), ) obj.Fixtures = ["G54"] for n in self.propertyEnumerations(): setattr(obj, n[0], n[1]) obj.PostProcessorOutputFile = PathPreferences.defaultOutputFile() obj.PostProcessor = postProcessors = PathPreferences.allEnabledPostProcessors( ) defaultPostProcessor = PathPreferences.defaultPostProcessor() # Check to see if default post processor hasn't been 'lost' (This can happen when Macro dir has changed) if defaultPostProcessor in postProcessors: obj.PostProcessor = defaultPostProcessor else: obj.PostProcessor = postProcessors[0] obj.PostProcessorArgs = PathPreferences.defaultPostProcessorArgs() obj.GeometryTolerance = PathPreferences.defaultGeometryTolerance() self.setupOperations(obj) self.setupSetupSheet(obj) self.setupBaseModel(obj, models) self.setupToolTable(obj) self.setFromTemplateFile(obj, templateFile) self.setupStock(obj)
def __init__(self, obj, base, templateFile=None): self.obj = obj obj.addProperty( "App::PropertyFile", "PostProcessorOutputFile", "Output", QtCore.QT_TRANSLATE_NOOP("App::Property", "The NC output file for this project")) obj.addProperty( "App::PropertyEnumeration", "PostProcessor", "Output", QtCore.QT_TRANSLATE_NOOP("App::Property", "Select the Post Processor")) obj.addProperty( "App::PropertyString", "PostProcessorArgs", "Output", QtCore.QT_TRANSLATE_NOOP( "App::Property", "Arguments for the Post Processor (specific to the script)")) obj.addProperty( "App::PropertyString", "Description", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "An optional description for this job")) obj.addProperty( "App::PropertyDistance", "GeometryTolerance", "Geometry", QtCore.QT_TRANSLATE_NOOP( "App::Property", "For computing Paths; smaller increases accuracy, but slows down computation" )) obj.addProperty( "App::PropertyLink", "Base", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "The base object for all operations")) obj.addProperty( "App::PropertyLink", "Stock", "Base", QtCore.QT_TRANSLATE_NOOP("PathJob", "Solid object to be used as stock.")) obj.addProperty( "App::PropertyLink", "Operations", "Base", QtCore.QT_TRANSLATE_NOOP( "PathJob", "Compound path of all operations in the order they are processed." )) obj.addProperty( "App::PropertyLinkList", "ToolController", "Base", QtCore.QT_TRANSLATE_NOOP( "PathJob", "Collection of tool controllers available for this job.")) obj.PostProcessorOutputFile = PathPreferences.defaultOutputFile() #obj.setEditorMode("PostProcessorOutputFile", 0) # set to default mode obj.PostProcessor = postProcessors = PathPreferences.allEnabledPostProcessors( ) defaultPostProcessor = PathPreferences.defaultPostProcessor() # Check to see if default post processor hasn't been 'lost' (This can happen when Macro dir has changed) if defaultPostProcessor in postProcessors: obj.PostProcessor = defaultPostProcessor else: obj.PostProcessor = postProcessors[0] obj.PostProcessorArgs = PathPreferences.defaultPostProcessorArgs() obj.GeometryTolerance = PathPreferences.defaultGeometryTolerance() ops = FreeCAD.ActiveDocument.addObject("Path::FeatureCompoundPython", "Operations") if ops.ViewObject: ops.ViewObject.Proxy = 0 ops.ViewObject.Visibility = False obj.Operations = ops obj.setEditorMode('Operations', 2) # hide obj.setEditorMode('Placement', 2) self.setupSetupSheet(obj) obj.Base = createResourceClone(obj, base, 'Base', 'BaseGeometry') obj.Proxy = self self.setFromTemplateFile(obj, templateFile) if not obj.Stock: stockTemplate = PathPreferences.defaultStockTemplate() if stockTemplate: obj.Stock = PathStock.CreateFromTemplate( obj, json.loads(stockTemplate)) if not obj.Stock: obj.Stock = PathStock.CreateFromBase(obj) if obj.Stock.ViewObject: obj.Stock.ViewObject.Visibility = False
def opExecute(self, obj): '''opExecute(obj) ... process surface operation''' PathLog.track() # OCL must be installed try: import ocl except: FreeCAD.Console.PrintError( translate("Path_Surface", "This operation requires OpenCamLib to be installed.") + "\n") return print("StepOver is " + str(obj.StepOver)) if obj.StepOver > 100: obj.StepOver = 100 if obj.StepOver < 1: obj.StepOver = 1 output = "" if obj.Comment != "": output += '(' + str(obj.Comment) + ')\n' output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str(obj.ToolController.Tool.Diameter) + ")" parentJob = PathUtils.findParentJob(obj) if parentJob is None: return print("base object: " + self.baseobject.Name) if self.baseobject.TypeId.startswith('Mesh'): mesh = self.baseobject.Mesh else: # try/except is for Path Jobs created before GeometryTolerance try: deflection = parentJob.GeometryTolerance except AttributeError: import PathScripts.PathPreferences as PathPreferences deflection = PathPreferences.defaultGeometryTolerance() self.baseobject.Shape.tessellate(0.5) mesh = MeshPart.meshFromShape(self.baseobject.Shape, Deflection=deflection) if obj.BoundBox == "BaseBoundBox": bb = mesh.BoundBox else: bb = parentJob.Stock.Shape.BoundBox s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] # offset the triangle in Z with DepthOffset t = ocl.Triangle(ocl.Point(p[0], p[1], p[2] + obj.DepthOffset.Value), ocl.Point(q[0], q[1], q[2] + obj.DepthOffset.Value), ocl.Point(r[0], r[1], r[2] + obj.DepthOffset.Value)) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) self.commandlist.extend(output)
def opExecute(self, obj): '''opExecute(obj) ... process surface operation''' PathLog.track() # OCL must be installed try: import ocl except: FreeCAD.Console.PrintError( translate( "Path_Surface", "This operation requires OpenCamLib to be installed.") + "\n") return print("StepOver is " + str(obj.StepOver)) if obj.StepOver > 100: obj.StepOver = 100 if obj.StepOver < 1: obj.StepOver = 1 output = "" if obj.Comment != "": output += '(' + str(obj.Comment) + ')\n' output += "(" + obj.Label + ")" output += "(Compensated Tool Path. Diameter: " + str( obj.ToolController.Tool.Diameter) + ")" parentJob = PathUtils.findParentJob(obj) if parentJob is None: return for base in self.model: print("base object: " + base.Name) if base.TypeId.startswith('Mesh'): mesh = base.Mesh else: # try/except is for Path Jobs created before GeometryTolerance try: deflection = parentJob.GeometryTolerance except AttributeError: import PathScripts.PathPreferences as PathPreferences deflection = PathPreferences.defaultGeometryTolerance() base.Shape.tessellate(0.5) mesh = MeshPart.meshFromShape(base.Shape, Deflection=deflection) if obj.BoundBox == "BaseBoundBox": bb = mesh.BoundBox else: bb = parentJob.Stock.Shape.BoundBox s = ocl.STLSurf() for f in mesh.Facets: p = f.Points[0] q = f.Points[1] r = f.Points[2] # offset the triangle in Z with DepthOffset t = ocl.Triangle( ocl.Point(p[0], p[1], p[2] + obj.DepthOffset.Value), ocl.Point(q[0], q[1], q[2] + obj.DepthOffset.Value), ocl.Point(r[0], r[1], r[2] + obj.DepthOffset.Value)) s.addTriangle(t) if obj.Algorithm == 'OCL Dropcutter': output = self._dropcutter(obj, s, bb) elif obj.Algorithm == 'OCL Waterline': output = self._waterline(obj, s, bb) self.commandlist.extend(output)