From da2b81312b96dbb7d2c2b265ad3a6f1bfa49405c Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Fri, 20 Oct 2017 04:28:31 +0800 Subject: [PATCH] Add trace part movement command --- Gui/Resources/icons/Assembly_Trace.svg | 966 +++++++++++++++++++++++++ assembly.py | 99 +-- gui.py | 73 ++ 3 files changed, 1093 insertions(+), 45 deletions(-) create mode 100644 Gui/Resources/icons/Assembly_Trace.svg diff --git a/Gui/Resources/icons/Assembly_Trace.svg b/Gui/Resources/icons/Assembly_Trace.svg new file mode 100644 index 0000000..41f7775 --- /dev/null +++ b/Gui/Resources/icons/Assembly_Trace.svg @@ -0,0 +1,966 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [J.L. Cercos-Pita] + + + Ship_CapacityCurve + 2014-12-12 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/Ship/resources/icons/Ship_CapacityCurve.svg + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assembly.py b/assembly.py index 8377469..a7ac9dc 100644 --- a/assembly.py +++ b/assembly.py @@ -547,55 +547,69 @@ class AsmElementLink(AsmBase): def setPlacement(part,pla,undoDocs,undoName=None): AsmElementLink.setPlacement(part,pla,undoDocs,undoName) - -class ViewProviderAsmElementLink(ViewProviderAsmBase): - def __init__(self,vobj): - self._draggingPart = None - self._draggingOffset = None - self._draggingOffsetInv = None - self._draggingUndos = None - self._draggingPlacement = None - super(ViewProviderAsmElementLink,self).__init__(vobj) - - def doubleClicked(self, vobj): - return vobj.Document.setEdit(vobj,1) - - def onExecute(self,info): - if not getattr(self,'_draggingPart',None): - return - self._draggingPart = info.Part - self._draggingPlacement = info.Placement.multiply( - FreeCAD.Placement(self._draggingOffset)) - self.ViewObject.DraggingPlacement = self._draggingPlacement - - def initDraggingPlacement(self): - obj = self.ViewObject.Object - info = obj.Proxy.getInfo() - self._draggingPart = info.Part +class AsmDraggingContext(object): + def __init__(self,info): + self.undos = None + self.part = info.Part rot = utils.getElementRotation(info.Shape) if not rot: # in case the shape has no normal, like a vertex, just use an empty # rotation, which means having the same rotation has the owner part. rot = FreeCAD.Rotation() pla = FreeCAD.Placement(utils.getElementPos(info.Shape),rot) - self._draggingOffset = FreeCAD.Placement(pla.toMatrix()) - self._draggingOffsetInv = FreeCAD.Placement(pla.toMatrix().inverse()) - self._draggingPlacement = info.Placement.multiply(pla) - mat = FreeCADGui.editDocument().EditingTransform - return (mat,self._draggingPlacement,info.Shape.BoundBox) + self.offset = FreeCAD.Placement(pla.toMatrix()) + self.offsetInv = FreeCAD.Placement(pla.toMatrix().inverse()) + self.placement = info.Placement.multiply(pla) + self.tracePoint = self.placement.Base + self.trace = None + + def update(self,info): + self.part = info.Part + pla = info.Placement.multiply(FreeCAD.Placement(self.offset)) + self.placement = pla + if asm3.gui.AsmCmdManager.Trace and \ + self.tracePoint.isEqual(pla.Base,1e5): + if not self.trace: + self.trace = FreeCAD.ActiveDocument.addObject( + 'Part::Polygon','AsmTrace') + self.trace.Nodes = {-1:self.tracePoint} + self.tracePoint = pla.Base + self.trace.Nodes = {-1:pla.Base} + self.trace.recompute() + return pla + + +class ViewProviderAsmElementLink(ViewProviderAsmBase): + def __init__(self,vobj): + self._draggingContext = None + super(ViewProviderAsmElementLink,self).__init__(vobj) + + def doubleClicked(self, vobj): + return vobj.Document.setEdit(vobj,1) + + def onExecute(self,info): + if not getattr(self,'_draggingContext',None): + return + self.ViewObject.DraggingPlacement = self._draggingContext.update(info) + + def initDraggingPlacement(self): + info = self.ViewObject.Object.Proxy.getInfo() + self._draggingContext = AsmDraggingContext(info) + return (FreeCADGui.editDocument().EditingTransform, + self._draggingContext.placement, + info.Shape.BoundBox) def onDragStart(self): - self._draggingUndos = set() + self._draggingContext.undos = set() def onDragMotion(self): - pla = self.ViewObject.DraggingPlacement.multiply( - self._draggingOffsetInv) - setPlacement(self._draggingPart,pla, - self._draggingUndos, 'Assembly drag') - - obj = self.ViewObject.Object + ctx = self._draggingContext + pla = self.ViewObject.DraggingPlacement.multiply(ctx.offsetInv) + setPlacement(ctx.part,pla,ctx.undos, 'Assembly drag') from PySide import QtCore,QtGui + + obj = self.ViewObject.Object if QtGui.QApplication.keyboardModifiers() == QtCore.Qt.ControlModifier: obj.getLinkedObject(False).recompute() obj.recompute() @@ -605,19 +619,14 @@ class ViewProviderAsmElementLink(ViewProviderAsmBase): asm3.solver.solve(obj.Proxy.getAssembly().Object) except RuntimeError as e: logger.error(e) - return self._draggingPlacement + return ctx.placement def onDragEnd(self): - for doc in self._draggingUndos: + for doc in self._draggingContext.undos: doc.commitTransaction() - self._draggingUndos.clear() def unsetEdit(self,_vobj,_mode): - self._draggingPart = None - self._draggingOffset = None - self._draggingOffsetInv = None - self._draggingUndos = None - self._draggingPlacement = None + self._draggingContext = None return False diff --git a/gui.py b/gui.py index 1f84647..c159874 100644 --- a/gui.py +++ b/gui.py @@ -59,6 +59,16 @@ class AsmCmdManager(ProxyType): name = mcs._defaultMenuGroupName mcs.Menus.setdefault(name,[]).append(cls) + def getParamGroup(cls): + return FreeCAD.ParamGet( + 'User parameter:BaseApp/Preferences/Mod/Assembly3') + + def getParam(cls,tp,name,default=None): + return getattr(cls.getParamGroup(),'Get'+tp)(name,default) + + def setParam(cls,tp,name,v): + getattr(cls.getParamGroup(),'Set'+tp)(name,v) + def workbenchActivated(cls): pass @@ -158,3 +168,66 @@ class AsmCmdAxialMove(AsmCmdMove): _iconName = 'Assembly_AxialMove.svg' _useCenterballDragger = False +class AsmCmdCheckable(AsmCmdBase): + _id = -2 + _action = None + _saveParam = False + + @classmethod + def getAttributeName(cls): + return cls.__name__[6:] + + @classmethod + def getChecked(cls): + return getattr(cls.__class__,cls.getAttributeName()) + + @classmethod + def setChecked(cls,v): + setattr(cls.__class__,cls.getAttributeName(),v) + cls.setParam('Bool',cls.getAttributeName(),v) + + @classmethod + def onRegister(cls): + if cls._saveParam: + v = cls.getParam('Bool',cls.getAttributeName(),False) + else: + v = False + cls.setChecked(v) + + @classmethod + def workbenchActivated(cls): + if cls._action: + return + from PySide import QtGui + mw = FreeCADGui.getMainWindow() + tb = mw.findChild(QtGui.QToolBar,cls._toolbarName) + if not tb: + logger.error('cannot find toolbar "{}"'.format(cls._toolbarName)) + return + name = cls.getName() + for action in tb.actions(): + if action.objectName() == name: + action.setCheckable(True) + action.setChecked(cls.getChecked()) + cls._action = action + break + if not cls._action: + cls._active = False + logger.error('cannot find action "{}"'.format(cls.getName())) + else: + cls._active = True + return + + @classmethod + def Activated(cls): + if not cls._action: + return + checked = not cls.getChecked() + cls.setChecked(checked) + cls._action.setChecked(checked) + +class AsmCmdTrace(AsmCmdCheckable): + _id = 4 + _menuText = 'Trace part move' + _iconName = 'Assembly_Trace.svg' +