| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import FreeCAD |
|
|
| if FreeCAD.GuiUp: |
| import FreeCADGui |
| from FreeCADGui import Workbench |
| else: |
| |
| class Workbench: |
| pass |
|
|
|
|
| FreeCAD.__unit_test__ += ["TestCAMGui"] |
|
|
|
|
| class PathCommandGroup: |
| def __init__(self, cmdlist, menu, tooltip=None): |
| self.cmdlist = cmdlist |
| self.menu = menu |
| if tooltip is None: |
| self.tooltip = menu |
| else: |
| self.tooltip = tooltip |
|
|
| def GetCommands(self): |
| return tuple(self.cmdlist) |
|
|
| def GetResources(self): |
| return {"MenuText": self.menu, "ToolTip": self.tooltip} |
|
|
| def IsActive(self): |
| if FreeCAD.ActiveDocument is not None: |
| for o in FreeCAD.ActiveDocument.Objects: |
| if o.Name[:3] == "Job": |
| return True |
| return False |
|
|
|
|
| class CAMWorkbench(Workbench): |
| "CAM workbench" |
|
|
| def __init__(self): |
| self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/CAM/Resources/icons/CAMWorkbench.svg" |
| self.__class__.MenuText = "CAM" |
| self.__class__.ToolTip = "CAM workbench" |
|
|
| def Initialize(self): |
| global PathCommandGroup |
|
|
| |
| import Path.Dressup.Gui.Preferences as PathPreferencesPathDressup |
| import Path.Tool.assets.ui.preferences as AssetPreferences |
| import Path.Main.Gui.PreferencesJob as PathPreferencesPathJob |
|
|
| translate = FreeCAD.Qt.translate |
|
|
| |
| import Path |
| import PathScripts |
| import PathGui |
| from PySide import QtCore, QtGui |
|
|
| FreeCADGui.addLanguagePath(":/translations") |
| FreeCADGui.addIconPath(":/icons") |
| import Path.GuiInit |
|
|
| from Path.Main.Gui import JobCmd as PathJobCmd |
| from Path.Main.Gui import SanityCmd as SanityCmd |
| from Path.Tool.toolbit.ui import cmd as PathToolBitCmd |
| from Path.Tool.library.ui import cmd as PathToolBitLibraryCmd |
|
|
| from Path.Tool.camassets import cam_assets |
|
|
| cam_assets.setup() |
|
|
| |
| from Path.Tool.migration.migration import CAMAssetMigrator |
|
|
| migrator = CAMAssetMigrator() |
| migrator.check_migration_needed() |
|
|
| from PySide.QtCore import QT_TRANSLATE_NOOP |
|
|
| import PathCommands |
| import subprocess |
| from packaging.version import Version, parse |
|
|
| FreeCADGui.addPreferencePage( |
| PathPreferencesPathJob.JobPreferencesPage, |
| QT_TRANSLATE_NOOP("QObject", "CAM"), |
| ) |
| FreeCADGui.addPreferencePage( |
| AssetPreferences.AssetPreferencesPage, |
| QT_TRANSLATE_NOOP("QObject", "CAM"), |
| ) |
| FreeCADGui.addPreferencePage( |
| PathPreferencesPathDressup.DressupPreferencesPage, |
| QT_TRANSLATE_NOOP("QObject", "CAM"), |
| ) |
|
|
| Path.GuiInit.Startup() |
|
|
| |
| projcmdlist = ["CAM_Job", "CAM_Sanity"] |
| postcmdlist = ["CAM_Post", "CAM_PostSelected"] |
| toolcmdlist = ["CAM_Inspect", "CAM_SelectLoop", "CAM_OpActiveToggle"] |
|
|
| simcmdlist = ["CAM_SimulatorGL", "CAM_Simulator"] |
| prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/CAM") |
| simLegacy = prefs.GetBool("DefaultSimulatorLegacy", False) |
| if simLegacy: |
| simcmdlist.reverse() |
|
|
| prepcmdlist = [ |
| "CAM_Comment", |
| "CAM_Stop", |
| "CAM_Custom", |
| "CAM_Probe", |
| ] |
| twodopcmdlist = [ |
| "CAM_Profile", |
| "CAM_Pocket_Shape", |
| "CAM_MillFacing", |
| "CAM_Helix", |
| "CAM_Adaptive", |
| "CAM_Slot", |
| ] |
| threedopcmdlist = ["CAM_Pocket3D"] |
| engravecmdlist = ["CAM_Engrave", "CAM_Deburr", "CAM_Vcarve"] |
| drillingcmdlist = ["CAM_Drilling"] |
| modcmdlist = ["CAM_OperationCopy", "CAM_Array", "CAM_SimpleCopy"] |
| dressupcmdlist = [ |
| "CAM_DressupArray", |
| "CAM_DressupAxisMap", |
| "CAM_DressupPathBoundary", |
| "CAM_DressupDogbone", |
| "CAM_DressupDragKnife", |
| "CAM_DressupLeadInOut", |
| "CAM_DressupRampEntry", |
| "CAM_DressupTag", |
| "CAM_DressupZCorrect", |
| ] |
| extracmdlist = [] |
| specialcmdlist = [] |
|
|
| toolcmdlist.extend(PathToolBitLibraryCmd.BarList) |
| toolbitcmdlist = PathToolBitLibraryCmd.MenuList |
|
|
| postcmdgroup = ["CAM_PostTools"] |
| FreeCADGui.addCommand( |
| "CAM_PostTools", |
| PathCommandGroup( |
| postcmdlist, |
| QT_TRANSLATE_NOOP("CAM_PostTools", "Post process Operations"), |
| ), |
| ) |
| simcmdgroup = ["CAM_SimTools"] |
| FreeCADGui.addCommand( |
| "CAM_SimTools", |
| PathCommandGroup( |
| simcmdlist, |
| QT_TRANSLATE_NOOP("CAM_SimTools", "Simulators"), |
| ), |
| ) |
| engravecmdgroup = ["CAM_EngraveTools"] |
| FreeCADGui.addCommand( |
| "CAM_EngraveTools", |
| PathCommandGroup( |
| engravecmdlist, |
| QT_TRANSLATE_NOOP("CAM_EngraveTools", "Engraving Operations"), |
| ), |
| ) |
| if Path.Preferences.experimentalFeaturesEnabled(): |
| drillingcmdlist.append("CAM_Tapping") |
|
|
| if set(["CAM_Drilling", "CAM_Tapping"]).issubset(drillingcmdlist): |
| drillingcmdgroup = ["CAM_DrillingTools"] |
| FreeCADGui.addCommand( |
| "CAM_DrillingTools", |
| PathCommandGroup( |
| drillingcmdlist, |
| QT_TRANSLATE_NOOP("CAM_DrillingTools", "Drilling Operations"), |
| ), |
| ) |
| else: |
| drillingcmdgroup = drillingcmdlist |
|
|
| dressupcmdgroup = ["CAM_DressupTools"] |
| FreeCADGui.addCommand( |
| "CAM_DressupTools", |
| PathCommandGroup( |
| dressupcmdlist, |
| QT_TRANSLATE_NOOP("CAM_DressupTools", "Dressup Operations"), |
| ), |
| ) |
| threedcmdgroup = threedopcmdlist |
| if Path.Preferences.experimentalFeaturesEnabled(): |
| prepcmdlist.append("CAM_PathShapeTC") |
| extracmdlist.extend(["CAM_Area", "CAM_Area_Workplane"]) |
| specialcmdlist.append("CAM_ThreadMilling") |
| twodopcmdlist.append("CAM_Slot") |
|
|
| if Path.Preferences.advancedOCLFeaturesEnabled(): |
| try: |
| r = subprocess.run( |
| ["camotics", "--version"], capture_output=True, text=True |
| ).stderr.strip() |
| v = parse(r) |
|
|
| if v >= Version("1.2.2"): |
| toolcmdlist.append("CAM_Camotics") |
| except (FileNotFoundError, ModuleNotFoundError): |
| pass |
| except subprocess.CalledProcessError as e: |
| print(f"Failed to execute camotics command: {e}") |
| except ValueError as ve: |
| print(f"Version error: {ve}") |
| except Exception as ex: |
| print(f"An unexpected error occurred: {ex}") |
|
|
| try: |
| try: |
| import ocl |
| except ImportError: |
| import opencamlib as ocl |
| from Path.Op.Gui import Surface |
| from Path.Op.Gui import Waterline |
|
|
| threedopcmdlist.extend(["CAM_Surface", "CAM_Waterline"]) |
| threedcmdgroup = ["CAM_3dTools"] |
| FreeCADGui.addCommand( |
| "CAM_3dTools", |
| PathCommandGroup( |
| threedopcmdlist, |
| QT_TRANSLATE_NOOP("CAM_3dTools", "3D Operations"), |
| ), |
| ) |
| except ImportError: |
| if not Path.Preferences.suppressOpenCamLibWarning(): |
| FreeCAD.Console.PrintError("OpenCamLib is not working!\n") |
|
|
| self.appendToolbar( |
| QT_TRANSLATE_NOOP("Workbench", "Project Setup"), |
| projcmdlist + postcmdgroup, |
| ) |
| self.appendToolbar( |
| QT_TRANSLATE_NOOP("Workbench", "Tool Commands"), |
| simcmdgroup + toolcmdlist, |
| ) |
| self.appendToolbar( |
| QT_TRANSLATE_NOOP("Workbench", "New Operations"), |
| twodopcmdlist + drillingcmdgroup + engravecmdgroup + threedcmdgroup, |
| ) |
| self.appendToolbar( |
| QT_TRANSLATE_NOOP("Workbench", "Path Modification"), modcmdlist + dressupcmdgroup |
| ) |
| if extracmdlist: |
| self.appendToolbar(QT_TRANSLATE_NOOP("Workbench", "Helpful Tools"), extracmdlist) |
|
|
| self.appendMenu( |
| [QT_TRANSLATE_NOOP("Workbench", "&CAM")], |
| projcmdlist |
| + postcmdlist |
| + ["CAM_ExportTemplate", "Separator"] |
| + simcmdlist |
| + toolcmdlist |
| + toolbitcmdlist |
| + ["Separator"] |
| + twodopcmdlist |
| + drillingcmdlist |
| + engravecmdlist |
| + ["Separator"] |
| + threedopcmdlist |
| + ["Separator"], |
| ) |
| self.appendMenu( |
| [ |
| QT_TRANSLATE_NOOP("Workbench", "&CAM"), |
| QT_TRANSLATE_NOOP("Workbench", "Path Dressup"), |
| ], |
| dressupcmdlist, |
| ) |
| self.appendMenu( |
| [ |
| QT_TRANSLATE_NOOP("Workbench", "&CAM"), |
| QT_TRANSLATE_NOOP("Workbench", "Supplemental Commands"), |
| ], |
| prepcmdlist, |
| ) |
| self.appendMenu( |
| [ |
| QT_TRANSLATE_NOOP("Workbench", "&CAM"), |
| QT_TRANSLATE_NOOP("Workbench", "Path Modification"), |
| ], |
| modcmdlist, |
| ) |
| if specialcmdlist: |
| self.appendMenu( |
| [ |
| QT_TRANSLATE_NOOP("Workbench", "&CAM"), |
| QT_TRANSLATE_NOOP("Workbench", "Specialty Operations"), |
| ], |
| specialcmdlist, |
| ) |
| if extracmdlist: |
| self.appendMenu([QT_TRANSLATE_NOOP("Workbench", "&CAM")], extracmdlist) |
|
|
| self.appendMenu([QT_TRANSLATE_NOOP("Workbench", "&CAM")], ["Separator"]) |
| self.appendMenu( |
| [ |
| QT_TRANSLATE_NOOP("Workbench", "&CAM"), |
| QT_TRANSLATE_NOOP("Workbench", "Utils"), |
| ], |
| ["CAM_PropertyBag"], |
| ) |
|
|
| self.dressupcmds = dressupcmdlist |
|
|
| curveAccuracy = Path.Preferences.defaultLibAreaCurveAccuracy() |
| if curveAccuracy: |
| Path.Area.setDefaultParams(Accuracy=curveAccuracy) |
|
|
| |
| import Path.Base.Gui.PreferencesAdvanced as PathPreferencesAdvanced |
| from Path.Preferences import preferences |
|
|
| FreeCADGui.addPreferencePage( |
| PathPreferencesAdvanced.AdvancedPreferencesPage, |
| QT_TRANSLATE_NOOP("QObject", "CAM"), |
| ) |
| Log("Loading CAM workbench... done\n") |
|
|
| def GetClassName(self): |
| return "Gui::PythonWorkbench" |
|
|
| def Activated(self): |
| |
| FreeCADGui.updateLocale() |
| |
|
|
| def Deactivated(self): |
| |
| pass |
|
|
| def ContextMenu(self, recipient): |
| import PathScripts |
|
|
| menuAppended = False |
| selection = FreeCADGui.Selection.getSelection() |
| if len(selection) == 1: |
| obj = selection[0] |
| selectedName = obj.Name |
| if obj.isDerivedFrom("Path::Feature"): |
| self.appendContextMenu("", "Separator") |
| self.appendContextMenu("", ["CAM_Inspect"]) |
| if "Remote" in selectedName: |
| self.appendContextMenu("", ["Refresh_Path"]) |
| if "Job" in selectedName: |
| self.appendContextMenu("", ["CAM_ExportTemplate"]) |
| menuAppended = True |
| if isinstance(obj.Proxy, Path.Op.Base.ObjectOp): |
| self.appendContextMenu("", ["CAM_OperationCopy", "CAM_OpActiveToggle"]) |
| if hasattr(obj, "StartPoint"): |
| self.appendContextMenu("", ["CAM_SetStartPoint"]) |
| menuAppended = True |
| if obj.isDerivedFrom("Path::Feature"): |
| if ( |
| "Profile" in selectedName |
| or "Contour" in selectedName |
| or "Dressup" in selectedName |
| or "Pocket" in selectedName |
| ): |
| self.appendContextMenu("", "Separator") |
| |
| |
| for cmd in self.dressupcmds: |
| self.appendContextMenu("Dressup", [cmd]) |
| menuAppended = True |
| if isinstance(obj.Proxy, Path.Tool.ToolBit): |
| self.appendContextMenu("", ["CAM_ToolBitSave", "CAM_ToolBitSaveAs"]) |
| menuAppended = True |
|
|
| if selection: |
| for obj in selection: |
| if not obj.isDerivedFrom("Path::Feature"): |
| break |
| else: |
| self.appendContextMenu("", ["CAM_Post", "CAM_PostSelected"]) |
|
|
| if menuAppended: |
| self.appendContextMenu("", "Separator") |
|
|
|
|
| Gui.addWorkbench(CAMWorkbench()) |
|
|
| FreeCAD.addImportType( |
| "GCode (*.nc *.NC *.gc *.GC *.ncc *.NCC *.ngc *.NGC *.cnc *.CNC *.tap *.TAP *.gcode *.GCODE)", |
| "PathGui", |
| ) |
|
|