diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt index d9d58e36c6..55583cebca 100644 --- a/src/Mod/Path/CMakeLists.txt +++ b/src/Mod/Path/CMakeLists.txt @@ -21,6 +21,7 @@ SET(PathScripts_SRCS PathCommands.py PathScripts/PathAreaOp.py PathScripts/PathArray.py + PathScripts/AxisMapDressup.py PathScripts/PathCircularHoleBase.py PathScripts/PathCircularHoleBaseGui.py PathScripts/PathComment.py diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py index e421de0f76..32d977a5b5 100644 --- a/src/Mod/Path/InitGui.py +++ b/src/Mod/Path/InitGui.py @@ -46,6 +46,7 @@ class PathWorkbench (Workbench): FreeCADGui.addLanguagePath(":/translations") FreeCADGui.addIconPath(":/icons") # load python modules + from PathScripts import AxisMapDressup.py from PathScripts import PathArray from PathScripts import PathComment from PathScripts import PathCustom diff --git a/src/Mod/Path/PathScripts/AxisMapDressup.py b/src/Mod/Path/PathScripts/AxisMapDressup.py new file mode 100644 index 0000000000..cfe3860419 --- /dev/null +++ b/src/Mod/Path/PathScripts/AxisMapDressup.py @@ -0,0 +1,169 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2016 sliptonic * +# * * +# * 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 Path +import math +import PathScripts.PathUtils as P +from PySide import QtCore, QtGui + +"""Axis remapping Dressup object and FreeCAD command. This dressup remaps one axis of motion to another. +For example, you can re-map the Y axis to A to control a 4th axis rotary.""" + +# Qt tanslation handling +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + + def translate(context, text, disambig=None): + return QtGui.QApplication.translate(context, text, disambig, _encoding) + +except AttributeError: + + def translate(context, text, disambig=None): + return QtGui.QApplication.translate(context, text, disambig) + + +class ObjectDressup: + + def __init__(self, obj): + maplist = ["X->A", "Y->A", "X->B", "Y->B", "X->C", "Y->C"] + obj.addProperty("App::PropertyLink", "Base","Path", "The base path to modify") + obj.addProperty("App::PropertyEnumeration", "axisMap", "Path", "The input mapping axis") + obj.addProperty("App::PropertyValue", "radius", "Path", "The radius of the wrapped axis") + obj.axisMap = maplist + obj.Proxy = self + + def __getstate__(self): + return None + + def __setstate__(self, state): + return None + + def _linear2angular(self, radius, length): + '''returns an angular distance in degrees to achieve a linear move of a given lenth''' + circum = 2 * math.pi * float(radius) + return 360 * (float(length) / circum) + + def execute(self, obj): + + inAxis = obj.axisMap[0] + outAxis = obj.axisMap[2] + + if obj.Base: + if obj.Base.isDerivedFrom("Path::Feature"): + if obj.Base.Path: + if obj.Base.Path.Commands: + newcommandlist = [] + for c in obj.Base.Path.Commands: + newparams = dict(c.Parameters) + remapvar = newparams.pop(obj.inAxis, None) + if remapvar is not None: + newparams[obj.outAxis] = remapvar + newcommand = Path.Command(c.Name, newparams) + newcommandlist.append(newcommand) + else: + newcommandlist.append(c) + obj.Base.Path.Commands = newcommandlist + + +class ViewProviderDressup: + + def __init__(self, vobj): + vobj.Proxy = self + + def attach(self, vobj): + self.Object = vobj.Object + return + + def claimChildren(self): + for i in self.Object.Base.InList: + if hasattr(i, "Group"): + group = i.Group + for g in group: + if g.Name == self.Object.Base.Name: + group.remove(g) + i.Group = group + print i.Group + return [self.Object.Base] + + def __getstate__(self): + return None + + def __setstate__(self, state): + return None + + def onDelete(self, arg1=None, arg2=None): + '''this makes sure that the base operation is added back to the project and visible''' + FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name).Visibility = True + P.addToProject(arg1.Object.Base) + return True + +class CommandPathDressup: + + def GetResources(self): + return {'Pixmap': 'Path-Dressup', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("AxisMap_Dressup", "Axis Map Dress-up"), + 'Accel': "P, S", + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("AxisMap_Dressup", "Remap one axis to another.")} + + def IsActive(self): + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False + + def Activated(self): + + # check that the selection contains exactly what we want + selection = FreeCADGui.Selection.getSelection() + if len(selection) != 1: + FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select one path object\n")) + return + if not selection[0].isDerivedFrom("Path::Feature"): + FreeCAD.Console.PrintError(translate("Path_Dressup", "The selected object is not a path\n")) + return + if selection[0].isDerivedFrom("Path::FeatureCompoundPython"): + FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select a Path object")) + return + + # everything ok! + FreeCAD.ActiveDocument.openTransaction(translate("Path_Dressup", "Create Dress-up")) + FreeCADGui.addModule("PathScripts.AxisMapDressup") + FreeCADGui.addModule("PathScripts.PathUtils") + FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "AxisMapDressup")') + FreeCADGui.doCommand('PathScripts.AxisMapDressup.ObjectDressup(obj)') + FreeCADGui.doCommand('obj.Base = FreeCAD.ActiveDocument.' + selection[0].Name) + FreeCADGui.doCommand('PathScripts.AxisMapDressup.ViewProviderDressup(obj.ViewObject)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') + FreeCADGui.doCommand('Gui.ActiveDocument.getObject(obj.Base.Name).Visibility = False') + FreeCAD.ActiveDocument.commitTransaction() + FreeCAD.ActiveDocument.recompute() + + +if FreeCAD.GuiUp: + # register the FreeCAD command + FreeCADGui.addCommand('AxisMap_Dressup', CommandPathDressup()) + +FreeCAD.Console.PrintLog("Loading PathDressup... done\n")