Download src/Mod/CAM/Path/Op/Custom.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 8.38 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/Path/Op/Custom.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/CAM/Path/Op/Custom.py
-
curl -L -o Custom.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/Path/Op/Custom.py
8.38 kB
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # *************************************************************************** | |
| # * Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> * | |
| # * * | |
| # * This program is free software; you can redistribute it and/or modify * | |
| # * it under the terms of the GNU Lesser General Public License (LGPL) * | |
| # * as published by the Free Software Foundation; either version 2 of * | |
| # * the License, or (at your option) any later version. * | |
| # * for detail see the LICENCE text file. * | |
| # * * | |
| # * This program is distributed in the hope that it will be useful, * | |
| # * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| # * GNU Library General Public License for more details. * | |
| # * * | |
| # * You should have received a copy of the GNU Library General Public * | |
| # * License along with this program; if not, write to the Free Software * | |
| # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * | |
| # * USA * | |
| # * * | |
| # *************************************************************************** | |
| import FreeCAD | |
| import FreeCADGui | |
| import os | |
| import Path | |
| import Path.Op.Base as PathOp | |
| from PySide.QtCore import QT_TRANSLATE_NOOP | |
| __title__ = "CAM Custom Operation" | |
| __author__ = "sliptonic (Brad Collette)" | |
| __url__ = "https://www.freecad.org" | |
| __doc__ = "CAM Custom object and FreeCAD command" | |
| if False: | |
| Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule()) | |
| Path.Log.trackModule(Path.Log.thisModule()) | |
| else: | |
| Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule()) | |
| translate = FreeCAD.Qt.translate | |
| class ObjectCustom(PathOp.ObjectOp): | |
| def propertyEnumerations(self, dataType="data"): | |
| """customOpPropertyEnumerations(dataType="data")... return property enumeration lists of specified dataType. | |
| Args: | |
| dataType = 'data', 'raw', 'translated' | |
| Notes: | |
| 'data' is list of internal string literals used in code | |
| 'raw' is list of (translated_text, data_string) tuples | |
| 'translated' is list of translated string literals | |
| """ | |
| # Enumeration lists for App::PropertyEnumeration properties | |
| enums = { | |
| "Source": [ | |
| (translate("PathCustom", "Text"), "Text"), | |
| (translate("PathCustom", "File"), "File"), | |
| ], | |
| } | |
| if dataType == "raw": | |
| return enums | |
| data = list() | |
| idx = 0 if dataType == "translated" else 1 | |
| Path.Log.debug(enums) | |
| for k, v in enumerate(enums): | |
| data.append((v, [tup[idx] for tup in enums[v]])) | |
| Path.Log.debug(data) | |
| return data | |
| def opFeatures(self, obj): | |
| return PathOp.FeatureTool | PathOp.FeatureCoolant | |
| def initOperation(self, obj): | |
| obj.addProperty( | |
| "App::PropertyEnumeration", | |
| "Source", | |
| "Path", | |
| "Source of gcode (text, file, ...)", | |
| ) | |
| obj.addProperty( | |
| "App::PropertyFile", | |
| "GcodeFile", | |
| "Path", | |
| "File containing gcode to be inserted", | |
| ) | |
| obj.addProperty( | |
| "App::PropertyStringList", | |
| "Gcode", | |
| "Path", | |
| QT_TRANSLATE_NOOP("App::Property", "The G-code to be inserted"), | |
| ) | |
| # populate the property enumerations | |
| for n in self.propertyEnumerations(): | |
| setattr(obj, n[0], n[1]) | |
| obj.Proxy = self | |
| self.setEditorModes(obj) | |
| def onChanged(self, obj, prop): | |
| if prop == "Source": | |
| self.setEditorModes(obj) | |
| if prop == "Active" and obj.ViewObject: | |
| obj.ViewObject.signalChangeIcon() | |
| def opOnDocumentRestored(self, obj): | |
| if not hasattr(obj, "Source"): | |
| obj.addProperty( | |
| "App::PropertyEnumeration", | |
| "Source", | |
| "Path", | |
| "Source of gcode (text, file, ...)", | |
| ) | |
| if not hasattr(obj, "GcodeFile"): | |
| obj.addProperty( | |
| "App::PropertyFile", | |
| "GcodeFile", | |
| "Path", | |
| "File containing gcode to be inserted", | |
| ) | |
| # populate the property enumerations | |
| for n in self.propertyEnumerations(): | |
| setattr(obj, n[0], n[1]) | |
| def onDocumentRestore(self, obj): | |
| self.setEditorModes(self, obj) | |
| def setEditorModes(self, obj, features=None): | |
| if not hasattr(obj, "Source"): | |
| return | |
| if obj.Source == "Text": | |
| obj.setEditorMode("GcodeFile", 2) | |
| obj.setEditorMode("Gcode", 0) | |
| elif obj.Source == "File": | |
| obj.setEditorMode("GcodeFile", 0) | |
| obj.setEditorMode("Gcode", 2) | |
| def findGcodeFile(self, filename): | |
| if os.path.exists(filename): | |
| # probably absolute, just return | |
| return filename | |
| doc_path = os.path.dirname(FreeCAD.ActiveDocument.FileName) | |
| prospective_path = os.path.join(doc_path, filename) | |
| if os.path.exists(prospective_path): | |
| return prospective_path | |
| def opExecute(self, obj): | |
| self.commandlist.append(Path.Command("(Begin Custom)")) | |
| errorNumLines = [] | |
| errorLines = [] | |
| counter = 0 | |
| if obj.Source == "Text" and obj.Gcode: | |
| for l in obj.Gcode: | |
| counter += 1 | |
| try: | |
| newcommand = Path.Command(str(l)) | |
| self.commandlist.append(newcommand) | |
| except ValueError: | |
| errorNumLines.append(counter) | |
| if len(errorLines) < 7: | |
| errorLines.append(f"{counter}: {str(l).strip()}") | |
| if errorLines: | |
| Path.Log.warning( | |
| translate("PathCustom", "Total invalid lines in Custom Text G-code: %s") | |
| % len(errorNumLines) | |
| ) | |
| elif obj.Source == "File" and len(obj.GcodeFile) > 0: | |
| gcode_file = self.findGcodeFile(obj.GcodeFile) | |
| # could not determine the path | |
| if not gcode_file: | |
| Path.Log.error( | |
| translate("PathCustom", "Custom file %s could not be found.") % obj.GcodeFile | |
| ) | |
| else: | |
| with open(gcode_file) as fd: | |
| for l in fd.readlines(): | |
| counter += 1 | |
| try: | |
| newcommand = Path.Command(str(l)) | |
| self.commandlist.append(newcommand) | |
| except ValueError: | |
| errorNumLines.append(counter) | |
| if len(errorLines) < 7: | |
| errorLines.append(f"{counter}: {str(l).strip()}") | |
| if errorLines: | |
| Path.Log.warning(f'"{gcode_file}"') | |
| Path.Log.warning( | |
| translate("PathCustom", "Total invalid lines in Custom File G-code: %s") | |
| % len(errorNumLines) | |
| ) | |
| if errorNumLines: | |
| Path.Log.warning( | |
| translate("PathCustom", "Please check lines: %s") | |
| % ", ".join(map(str, errorNumLines)) | |
| ) | |
| if len(errorLines) > 7: | |
| errorLines.append("...") | |
| Path.Log.warning("\n" + "\n".join(errorLines)) | |
| self.commandlist.append(Path.Command("(End Custom)")) | |
| def SetupProperties(): | |
| setup = [] | |
| return setup | |
| def Create(name, obj=None, parentJob=None): | |
| """Create(name) ... Creates and returns a Custom operation.""" | |
| if obj is None: | |
| obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) | |
| obj.Proxy = ObjectCustom(obj, name, parentJob) | |
| return obj | |