assembly: fix element offset/flip menu action
This commit is contained in:
parent
c60a7b7f35
commit
ebd9dd8a68
|
@ -1259,7 +1259,7 @@ class ViewProviderAsmElement(ViewProviderAsmOnTop):
|
||||||
menu.addAction(action)
|
menu.addAction(action)
|
||||||
|
|
||||||
action = QtGui.QAction(QtGui.QIcon(),
|
action = QtGui.QAction(QtGui.QIcon(),
|
||||||
"Attach" if obj.Detach else "Detach", menu)
|
"Attach element" if obj.Detach else "Detach element", menu)
|
||||||
if obj.Detach:
|
if obj.Detach:
|
||||||
action.setToolTip('Attach this element to its linked geometry,\n'
|
action.setToolTip('Attach this element to its linked geometry,\n'
|
||||||
'so that it will auto update on change.')
|
'so that it will auto update on change.')
|
||||||
|
@ -1271,38 +1271,44 @@ class ViewProviderAsmElement(ViewProviderAsmOnTop):
|
||||||
menu.addAction(action)
|
menu.addAction(action)
|
||||||
|
|
||||||
if obj.Proxy.isBroken():
|
if obj.Proxy.isBroken():
|
||||||
action = QtGui.QAction(QtGui.QIcon(), "Fix", menu)
|
action = QtGui.QAction(QtGui.QIcon(), "Fix element", menu)
|
||||||
action.setToolTip('Auto fix broken element')
|
action.setToolTip('Auto fix broken element')
|
||||||
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),vobj.Proxy.fix)
|
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),vobj.Proxy.fix)
|
||||||
menu.addAction(action)
|
menu.addAction(action)
|
||||||
|
|
||||||
action = QtGui.QAction(QtGui.QIcon(), 'Offset', menu)
|
action = QtGui.QAction(QtGui.QIcon(), 'Offset element', menu)
|
||||||
action.setToolTip('Activate dragger to offset this element')
|
action.setToolTip('Activate dragger to offset this element')
|
||||||
menu.addAction(action)
|
menu.addAction(action)
|
||||||
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),vobj2.Proxy.offset)
|
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),vobj2.Proxy.offset)
|
||||||
|
|
||||||
|
if vobj2.Object.Offset != FreeCAD.Placement():
|
||||||
def setupContextMenu(self,vobj,menu):
|
action = QtGui.QAction(QtGui.QIcon(), 'Reset offset', menu)
|
||||||
ViewProviderAsmElement.setupMenu(menu, vobj, vobj)
|
action.setToolTip('Clear offset of this element')
|
||||||
|
menu.addAction(action)
|
||||||
|
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),vobj2.Proxy.resetOffset)
|
||||||
|
|
||||||
action = QtGui.QAction(QtGui.QIcon(), 'Flip element', menu)
|
action = QtGui.QAction(QtGui.QIcon(), 'Flip element', menu)
|
||||||
action.setToolTip('Flip this element\' Z normal by rotating 180 degree\n'
|
action.setToolTip('Flip this element\' Z normal by rotating 180 degree\n'
|
||||||
'along the X axis (or Y axis by holding the CTRL key).\n\n'
|
'along the X axis (or Y axis by holding the CTRL key).\n\n'
|
||||||
'Note that this is only effective when for elements\n'
|
'Note that depending on the type of constraint and the\n'
|
||||||
'used in "Attachment" constraint. For others, please\n'
|
'order of the selected element, flipping element may not\n'
|
||||||
'try "Flip part" instead.')
|
'be effective. You can try "Flip part" instead.')
|
||||||
menu.addAction(action)
|
menu.addAction(action)
|
||||||
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),self.flip)
|
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),vobj2.Proxy.flip)
|
||||||
|
|
||||||
action = QtGui.QAction(QtGui.QIcon(), 'Flip part', menu)
|
action = QtGui.QAction(QtGui.QIcon(), 'Flip part', menu)
|
||||||
action.setToolTip('Flip the owner part using this element Z normal as\n'
|
action.setToolTip('Flip the owner part using this element Z normal as\n' \
|
||||||
'reference, which is done by rotating 180 degree along\n'
|
'reference, which is done by rotating 180 degree along\n' \
|
||||||
'the element\'s X axis (or Y axis by holding the CTRL key).\n\n'
|
'the element\'s X axis (or Y axis by holding the CTRL key).\n\n'
|
||||||
'Note that this won\'t work for elements in "Attachment"\n'
|
'Note that depending on the type of constraint and the\n'
|
||||||
'constraint. Please try "Flip element" instead.')
|
'order of the selected element, flipping part may not\n'
|
||||||
|
'be effective. You can try "Flip element" instead.')
|
||||||
menu.addAction(action)
|
menu.addAction(action)
|
||||||
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),self.flipPart)
|
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),vobj2.Proxy.flipPart)
|
||||||
|
|
||||||
|
|
||||||
|
def setupContextMenu(self,vobj,menu):
|
||||||
|
ViewProviderAsmElement.setupMenu(menu, vobj, vobj)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def fix(self):
|
def fix(self):
|
||||||
|
@ -1331,7 +1337,18 @@ class ViewProviderAsmElement(ViewProviderAsmOnTop):
|
||||||
return mover.movePart(element=self.ViewObject.Object, moveElement=True)
|
return mover.movePart(element=self.ViewObject.Object, moveElement=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def doFlip(obj, info, flipElement=False):
|
def doResetOffset(obj):
|
||||||
|
FreeCAD.setActiveTransaction('Reset offset')
|
||||||
|
obj.Offset = FreeCAD.Placement()
|
||||||
|
obj.recompute(True)
|
||||||
|
FreeCAD.closeActiveTransaction()
|
||||||
|
|
||||||
|
def resetOffset(self):
|
||||||
|
obj = self.ViewObject.Object
|
||||||
|
ViewProviderAsmElement.doResetOffset(obj)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def doFlip(obj, info, flipElement):
|
||||||
if QtGui.QApplication.keyboardModifiers()==QtCore.Qt.ControlModifier:
|
if QtGui.QApplication.keyboardModifiers()==QtCore.Qt.ControlModifier:
|
||||||
rot = FreeCAD.Rotation(FreeCAD.Vector(0,1,0),180)
|
rot = FreeCAD.Rotation(FreeCAD.Vector(0,1,0),180)
|
||||||
else:
|
else:
|
||||||
|
@ -1345,8 +1362,9 @@ class ViewProviderAsmElement(ViewProviderAsmOnTop):
|
||||||
obj.Offset = rot.multiply(obj.Offset)
|
obj.Offset = rot.multiply(obj.Offset)
|
||||||
else:
|
else:
|
||||||
offset = utils.getElementPlacement(obj.getSubObject(''))
|
offset = utils.getElementPlacement(obj.getSubObject(''))
|
||||||
offset = offset.inverse().multiply(rot).multiply(offset)
|
offset = offset.multiply(rot).multiply(offset.inverse())
|
||||||
setPlacement(info.Part, info.Placement.multiply(offset))
|
setPlacement(info.Part, offset.multiply(info.Placement))
|
||||||
|
obj.recompute(True)
|
||||||
FreeCAD.closeActiveTransaction()
|
FreeCAD.closeActiveTransaction()
|
||||||
except Exception:
|
except Exception:
|
||||||
FreeCAD.closeActiveTransaction(True)
|
FreeCAD.closeActiveTransaction(True)
|
||||||
|
@ -1354,7 +1372,7 @@ class ViewProviderAsmElement(ViewProviderAsmOnTop):
|
||||||
|
|
||||||
def flip(self):
|
def flip(self):
|
||||||
obj = self.ViewObject.Object
|
obj = self.ViewObject.Object
|
||||||
ViewProviderAsmElement.doFlip(obj, obj.Proxy.getInfo())
|
ViewProviderAsmElement.doFlip(obj, obj.Proxy.getInfo(), True)
|
||||||
|
|
||||||
def flipPart(self):
|
def flipPart(self):
|
||||||
obj = self.ViewObject.Object
|
obj = self.ViewObject.Object
|
||||||
|
@ -2052,25 +2070,23 @@ class ViewProviderAsmElementLink(ViewProviderAsmOnTop):
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ViewProviderAsmElement.setupMenu(menu, element.ViewObject, vobj)
|
ViewProviderAsmElement.setupMenu(menu, element.ViewObject, vobj)
|
||||||
|
|
||||||
action = QtGui.QAction(QtGui.QIcon(), 'Flip', menu)
|
|
||||||
action.setToolTip('For element link inside an "Attachment" constraint,\n'
|
|
||||||
'flip the element\'s Z normal by rotating 180 degree along\n'
|
|
||||||
'its X axis (or Y axis by holding the CTRL key). For other\n'
|
|
||||||
'constraint, flip the owner part instead.')
|
|
||||||
menu.addAction(action)
|
|
||||||
QtCore.QObject.connect(action,QtCore.SIGNAL("triggered()"),self.flip)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def offset(self):
|
def offset(self):
|
||||||
from . import mover
|
from . import mover
|
||||||
return mover.movePart(element=self.ViewObject.Object, moveElement=True)
|
return mover.movePart(element=self.ViewObject.Object, moveElement=True)
|
||||||
|
|
||||||
|
def resetOffset(self):
|
||||||
|
obj = self.ViewObject.Object
|
||||||
|
ViewProviderAsmElement.doResetOffset(obj)
|
||||||
|
|
||||||
def flip(self):
|
def flip(self):
|
||||||
obj = self.ViewObject.Object
|
obj = self.ViewObject.Object
|
||||||
ViewProviderAsmElement.doFlip(obj, obj.Proxy.getInfo(),
|
ViewProviderAsmElement.doFlip(obj, obj.Proxy.getInfo(), True)
|
||||||
Constraint.isAttachment(obj.Proxy.parent.Object))
|
|
||||||
|
def flipPart(self):
|
||||||
|
obj = self.ViewObject.Object
|
||||||
|
ViewProviderAsmElement.doFlip(obj, obj.Proxy.getInfo(), False)
|
||||||
|
|
||||||
|
|
||||||
class AsmConstraint(AsmGroup):
|
class AsmConstraint(AsmGroup):
|
||||||
|
@ -4295,6 +4311,9 @@ class ViewProviderAssembly(ViewProviderAsmGroup):
|
||||||
def onDragEnd(self):
|
def onDragEnd(self):
|
||||||
try:
|
try:
|
||||||
if getattr(self,'_movingPart',None):
|
if getattr(self,'_movingPart',None):
|
||||||
|
pla = self._movingPart.dragEnd()
|
||||||
|
if pla:
|
||||||
|
self.ViewObject.DraggingPlacement = pla
|
||||||
FreeCAD.closeActiveTransaction()
|
FreeCAD.closeActiveTransaction()
|
||||||
return True
|
return True
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -49,11 +49,6 @@ class AsmMovingPart(object):
|
||||||
# Place the dragger at element's current (maybe offseted) shape
|
# Place the dragger at element's current (maybe offseted) shape
|
||||||
# center point in assembly coordinate
|
# center point in assembly coordinate
|
||||||
self.draggerPlacement = utils.getElementPlacement(shape)
|
self.draggerPlacement = utils.getElementPlacement(shape)
|
||||||
# calculate the placement of an unoffseted element in assembly coordinate
|
|
||||||
self.offset = utils.getElementPlacement(element.getSubObject('',transform=False))
|
|
||||||
# Calculate the placement to transform the unoffseted element
|
|
||||||
# shape to the origin of its own coordinate space
|
|
||||||
self.offsetInv = self.offset.inverse()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# if we are not moving the element, but its owner part, transform
|
# if we are not moving the element, but its owner part, transform
|
||||||
|
@ -135,9 +130,7 @@ class AsmMovingPart(object):
|
||||||
shape = self.element.getSubObject('')
|
shape = self.element.getSubObject('')
|
||||||
pla = utils.getElementPlacement(shape)
|
pla = utils.getElementPlacement(shape)
|
||||||
elif utils.isDraftObject(info.Part):
|
elif utils.isDraftObject(info.Part):
|
||||||
pos = utils.getElementPos(info.Shape)
|
pla = utils.getElementPlacement(info.Shape)
|
||||||
rot = utils.getElementRotation(info.Shape)
|
|
||||||
pla = info.Placement.multiply(FreeCAD.Placement(pos,rot))
|
|
||||||
else:
|
else:
|
||||||
pla = info.Placement.multiply(self.offset)
|
pla = info.Placement.multiply(self.offset)
|
||||||
logger.trace('part move update {}: {}',objName(info.Parent),pla)
|
logger.trace('part move update {}: {}',objName(info.Parent),pla)
|
||||||
|
@ -158,6 +151,15 @@ class AsmMovingPart(object):
|
||||||
mat = FreeCADGui.editDocument().EditingTransform
|
mat = FreeCADGui.editDocument().EditingTransform
|
||||||
return mat.multiply(self.draggerPlacement.Base)
|
return mat.multiply(self.draggerPlacement.Base)
|
||||||
|
|
||||||
|
def dragEnd(self):
|
||||||
|
if self.moveElement and gui.AsmCmdManager.AutoRecompute:
|
||||||
|
from . import solver
|
||||||
|
if not logger.catch('solver exception when moving element',
|
||||||
|
solver.solve, self.objs):
|
||||||
|
self.assembly.Object.recompute(True)
|
||||||
|
else:
|
||||||
|
return self.update()
|
||||||
|
|
||||||
def move(self):
|
def move(self):
|
||||||
info = self.info
|
info = self.info
|
||||||
part = info.Part
|
part = info.Part
|
||||||
|
@ -168,8 +170,11 @@ class AsmMovingPart(object):
|
||||||
rollback = []
|
rollback = []
|
||||||
if self.moveElement:
|
if self.moveElement:
|
||||||
updatePla = False
|
updatePla = False
|
||||||
offset = utils.roundPlacement(self.offsetInv.multiply(pla))
|
# obtain the placement of an unoffseted element in assembly coordinate
|
||||||
self.element.Offset = offset
|
offset = utils.getElementPlacement(self.element.getSubObject('',transform=False))
|
||||||
|
self.element.Offset = utils.roundPlacement(offset.inverse().multiply(pla))
|
||||||
|
self.element.recompute(True)
|
||||||
|
return
|
||||||
elif not info.Subname.startswith('Face') and utils.isDraftWire(part):
|
elif not info.Subname.startswith('Face') and utils.isDraftWire(part):
|
||||||
updatePla = False
|
updatePla = False
|
||||||
if info.Subname.startswith('Vertex'):
|
if info.Subname.startswith('Vertex'):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user