Download src/Mod/CAM/PathCommands.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 11.3 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/PathCommands.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/CAM/PathCommands.py
-
curl -L -o PathCommands.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/PathCommands.py
11.3 kB
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # *************************************************************************** | |
| # * Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> * | |
| # * * | |
| # * 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 Part | |
| import Path | |
| import traceback | |
| import Path.Dressup.Utils as PathDressup | |
| from PathScripts.PathUtils import loopdetect | |
| from PathScripts.PathUtils import wiredetect | |
| from PathScripts.PathUtils import horizontalEdgeLoop | |
| from PathScripts.PathUtils import tangentEdgeLoop | |
| from PathScripts.PathUtils import horizontalFaceLoop | |
| from PathScripts.PathUtils import addToJob | |
| from PathScripts.PathUtils import findParentJob | |
| from PySide.QtCore import QT_TRANSLATE_NOOP | |
| if FreeCAD.GuiUp: | |
| import FreeCADGui | |
| translate = FreeCAD.Qt.translate | |
| __title__ = "FreeCAD Path Commands" | |
| __author__ = "sliptonic" | |
| __url__ = "https://www.freecad.org" | |
| class _CommandSelectLoop: | |
| "the Path command to complete loop selection definition" | |
| def __init__(self): | |
| self.obj = None | |
| self.sub = [] | |
| self.active = False | |
| def GetResources(self): | |
| return { | |
| "Pixmap": "CAM_SelectLoop", | |
| "MenuText": QT_TRANSLATE_NOOP("CAM_SelectLoop", "Finish Selecting Loop"), | |
| "Accel": "P, L", | |
| "ToolTip": QT_TRANSLATE_NOOP( | |
| "CAM_SelectLoop", | |
| "Completes the selection of edges or faces that form a loop" | |
| "\n\nSelect faces: searching loop faces which form the walls." | |
| "\n\nSelect one edge: searching loop edges in horizontal plane" | |
| "\nor wire which contain selected edge." | |
| "\n\nSelect two edges: searching loop edges in wires of the shape" | |
| "\nor tangent edges.", | |
| ), | |
| "CmdType": "ForEdit", | |
| } | |
| def IsActive(self): | |
| if bool(FreeCADGui.Selection.getSelection()) is False: | |
| return False | |
| try: | |
| sel = FreeCADGui.Selection.getSelectionEx()[0] | |
| if sel.Object == self.obj and sel.SubElementNames == self.sub: | |
| return self.active | |
| self.obj = sel.Object | |
| self.sub = sel.SubElementNames | |
| if sel.SubObjects: | |
| # self.active = self.formsPartOfALoop(sel.Object, sel.SubObjects[0], sel.SubElementNames) | |
| self.active = True | |
| else: | |
| self.active = False | |
| return self.active | |
| except Exception as exc: | |
| Path.Log.error(exc) | |
| traceback.print_exc(exc) | |
| return False | |
| def Activated(self): | |
| from PathScripts.PathUtils import horizontalEdgeLoop, horizontalFaceLoop | |
| if not FreeCADGui.Selection.getSelectionEx(): | |
| return | |
| sel = FreeCADGui.Selection.getSelectionEx()[0] | |
| if not sel.SubObjects: | |
| return | |
| obj = sel.Object | |
| sub = sel.SubObjects | |
| names = sel.SubElementNames | |
| loop = None | |
| # Face selection | |
| if "Face" in names[0]: | |
| loop = horizontalFaceLoop(obj, sub[0], names) | |
| if loop: | |
| FreeCADGui.Selection.clearSelection() | |
| FreeCADGui.Selection.addSelection(obj, loop) | |
| return | |
| elif "Edge" in names[0]: | |
| if len(sub) == 1: | |
| # One edge selected: searching horizontal edge loop | |
| loop = horizontalEdgeLoop(obj, sub[0], verbose=True) | |
| elif len(sub) >= 2: | |
| # Two edges selected: searching wire in shape which contain both edges | |
| loop = loopdetect(obj, sub[0], sub[1]) | |
| if not loop: | |
| # Two edges selected: searching edges in tangency | |
| loop = tangentEdgeLoop(obj, sub[0]) | |
| if not loop: | |
| # Searching any wire with first selected edge | |
| loop = wiredetect(obj, names[0]) | |
| if isinstance(loop, list) and len(loop) > 0 and isinstance(loop[0], Part.Edge): | |
| # Select edges from list | |
| objEdges = obj.Shape.Edges | |
| FreeCADGui.Selection.clearSelection() | |
| for el in loop: | |
| for eo in objEdges: | |
| if eo.hashCode() == el.hashCode(): | |
| FreeCADGui.Selection.addSelection(obj, f"Edge{objEdges.index(eo) + 1}") | |
| return | |
| Path.Log.warning(translate("CAM_SelectLoop", "Closed loop detection failed.")) | |
| def formsPartOfALoop(self, obj, sub, names): | |
| try: | |
| if names[0][0:4] != "Edge": | |
| if names[0][0:4] == "Face" and horizontalFaceLoop(obj, sub, names): | |
| return True | |
| return False | |
| if len(names) == 1 and horizontalEdgeLoop(obj, sub): | |
| return True | |
| if len(names) == 1 or names[1][0:4] != "Edge": | |
| return False | |
| return True | |
| except Exception: | |
| return False | |
| if FreeCAD.GuiUp: | |
| FreeCADGui.addCommand("CAM_SelectLoop", _CommandSelectLoop()) | |
| class _ToggleOperation: | |
| "command definition to toggle Operation Active state" | |
| def GetResources(self): | |
| return { | |
| "Pixmap": "CAM_OpActive", | |
| "MenuText": QT_TRANSLATE_NOOP("CAM_OpActiveToggle", "Toggle Operation"), | |
| "Accel": "P, X", | |
| "ToolTip": QT_TRANSLATE_NOOP( | |
| "CAM_OpActiveToggle", "Toggles the active state of the operation" | |
| ), | |
| "CmdType": "ForEdit", | |
| } | |
| def IsActive(self): | |
| selection = FreeCADGui.Selection.getSelection() | |
| if not selection: | |
| return False | |
| if len(selection) == 1: | |
| # allows to toggle all operations in Job | |
| sel = selection[0] | |
| if hasattr(sel, "Group") and sel.Name.startswith("Job"): | |
| return True | |
| if hasattr(sel, "Group") and sel.Name.startswith("Operations"): | |
| return True | |
| for sel in selection: | |
| baseOp = Path.Dressup.Utils.baseOp(sel) | |
| if not hasattr(baseOp, "Active"): | |
| return False | |
| return True | |
| def Activated(self): | |
| selection = FreeCADGui.Selection.getSelection() | |
| if (len(selection) == 1 and hasattr(selection[0], "Group")) and ( | |
| selection[0].Name.startswith("Job") or selection[0].Name.startswith("Operations") | |
| ): | |
| sel = selection[0] | |
| # process all Operations in Job | |
| if sel.Name.startswith("Job"): | |
| selection = sel.Operations.Group | |
| elif sel.Name.startswith("Operations"): | |
| selection = sel.Group | |
| states = [Path.Dressup.Utils.baseOp(sel).Active for sel in selection] | |
| if all(states) or not any(states): | |
| # all operations in one state (active or inactive) - toggle state | |
| for sel in selection: | |
| baseOp = Path.Dressup.Utils.baseOp(sel) | |
| baseOp.Active = not baseOp.Active | |
| else: | |
| # operations in different states - set Active state | |
| for sel in selection: | |
| baseOp = Path.Dressup.Utils.baseOp(sel) | |
| baseOp.Active = True | |
| else: | |
| for sel in selection: | |
| baseOp = Path.Dressup.Utils.baseOp(sel) | |
| baseOp.Active = not baseOp.Active | |
| FreeCAD.ActiveDocument.recompute() | |
| if FreeCAD.GuiUp: | |
| FreeCADGui.addCommand("CAM_OpActiveToggle", _ToggleOperation()) | |
| class _CopyOperation: | |
| "the Path Copy Operation command definition" | |
| def GetResources(self): | |
| return { | |
| "Pixmap": "CAM_OpCopy", | |
| "MenuText": QT_TRANSLATE_NOOP("CAM_OperationCopy", "Copy Operation"), | |
| "ToolTip": QT_TRANSLATE_NOOP("CAM_OperationCopy", "Copies the operation in the job"), | |
| "CmdType": "ForEdit", | |
| } | |
| def IsActive(self): | |
| selection = FreeCADGui.Selection.getSelection() | |
| if not selection: | |
| return False | |
| if any([not hasattr(sel, "Path") for sel in selection]): | |
| return False | |
| if any([sel.Name.startswith("Job") for sel in selection]): | |
| return False | |
| return True | |
| def Activated(self): | |
| selection = FreeCADGui.Selection.getSelection() | |
| for sel in selection: | |
| job = findParentJob(sel) | |
| prevOp = PathDressup.baseOp(sel) | |
| prevOpCopy = FreeCAD.ActiveDocument.copyObject(prevOp, False) | |
| while prevOp != sel: | |
| # recursive processing Dressup | |
| op = sel | |
| while op.Base != prevOp: | |
| # get higher level operation | |
| op = op.Base | |
| opCopy = FreeCAD.ActiveDocument.copyObject(op, False) | |
| opCopy.Base = prevOpCopy | |
| prevOpCopy = opCopy | |
| prevOp = op | |
| # add to Job top object | |
| addToJob(prevOpCopy, job.Name) | |
| if FreeCAD.GuiUp: | |
| FreeCADGui.addCommand("CAM_OperationCopy", _CopyOperation()) | |
| # \c findShape() is referenced from Gui/Command.cpp and used by Path.Area commands. | |
| # Do not remove! | |
| def findShape(shape, subname=None, subtype=None): | |
| """To find a higher order shape containing the subshape with subname. | |
| E.g. to find the wire containing 'Edge1' in shape, | |
| findShape(shape,'Edge1','Wires') | |
| """ | |
| if not subname: | |
| return shape | |
| ret = shape.getElement(subname) | |
| if not subtype or not ret or ret.isNull(): | |
| return ret | |
| if subname.startswith("Face"): | |
| tp = "Faces" | |
| elif subname.startswith("Edge"): | |
| tp = "Edges" | |
| elif subname.startswith("Vertex"): | |
| tp = "Vertex" | |
| else: | |
| return ret | |
| for obj in getattr(shape, subtype): | |
| for sobj in getattr(obj, tp): | |
| if sobj.isEqual(ret): | |
| return obj | |
| return ret | |