assembly: add 'Offset' property to AsmElement
This commit is contained in:
parent
fba1254627
commit
e3bdfffec7
99
assembly.py
99
assembly.py
|
@ -199,14 +199,22 @@ class ViewProviderAsmPartGroup(ViewProviderAsmGroup):
|
||||||
class AsmElement(AsmBase):
|
class AsmElement(AsmBase):
|
||||||
def __init__(self,parent):
|
def __init__(self,parent):
|
||||||
self._initializing = True
|
self._initializing = True
|
||||||
self.shape = None
|
self.info = None
|
||||||
self.parent = getProxy(parent,AsmElementGroup)
|
self.parent = getProxy(parent,AsmElementGroup)
|
||||||
super(AsmElement,self).__init__()
|
super(AsmElement,self).__init__()
|
||||||
|
|
||||||
def linkSetup(self,obj):
|
def linkSetup(self,obj):
|
||||||
super(AsmElement,self).linkSetup(obj)
|
super(AsmElement,self).linkSetup(obj)
|
||||||
obj.configLinkProperty('LinkedObject')
|
if not hasattr(obj,'Offset'):
|
||||||
# obj.setPropertyStatus('LinkedObject','Immutable')
|
obj.addProperty("App::PropertyPlacement","Offset"," Link",'')
|
||||||
|
if not hasattr(obj,'Placement'):
|
||||||
|
obj.addProperty("App::PropertyPlacement","Placement"," Link",'')
|
||||||
|
obj.setPropertyStatus('Placement',['Immutable','Hidden'])
|
||||||
|
if not hasattr(obj,'LinkTransform'):
|
||||||
|
obj.addProperty("App::PropertyBool","LinkTransform"," Link",'')
|
||||||
|
obj.LinkTransform = True
|
||||||
|
obj.setPropertyStatus('LinkTransform',['Immutable','Hidden'])
|
||||||
|
obj.configLinkProperty('LinkedObject','Placement','LinkTransform')
|
||||||
obj.setPropertyStatus('LinkedObject','ReadOnly')
|
obj.setPropertyStatus('LinkedObject','ReadOnly')
|
||||||
|
|
||||||
def attach(self,obj):
|
def attach(self,obj):
|
||||||
|
@ -226,23 +234,38 @@ class AsmElement(AsmBase):
|
||||||
|
|
||||||
def onChanged(self,_obj,prop):
|
def onChanged(self,_obj,prop):
|
||||||
parent = getattr(self,'parent',None)
|
parent = getattr(self,'parent',None)
|
||||||
if parent and \
|
if not parent or FreeCAD.isRestoring():
|
||||||
not getattr(self,'_initializing',False) and \
|
return
|
||||||
prop=='Label':
|
if prop=='Offset':
|
||||||
|
self.updatePlacement()
|
||||||
|
elif prop == 'Label':
|
||||||
parent.Object.cacheChildLabel()
|
parent.Object.cacheChildLabel()
|
||||||
|
if prop not in _IgnoredProperties and \
|
||||||
|
not Constraint.isDisabled(parent.Object):
|
||||||
|
Assembly.autoSolve()
|
||||||
|
|
||||||
def execute(self,_obj):
|
def execute(self,_obj):
|
||||||
# self.getShape(True)
|
self.updatePlacement()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def getShape(self,refresh=False):
|
def updatePlacement(self):
|
||||||
if not refresh:
|
obj = getattr(self,'Object',None)
|
||||||
ret = getattr(self,'shape',None)
|
if not obj:
|
||||||
if ret:
|
return
|
||||||
return ret
|
if obj.Offset.isIdentity():
|
||||||
self.shape = None
|
if obj.Placement.isIdentity():
|
||||||
self.shape = self.Object.getSubObject('')
|
return
|
||||||
return self.shape
|
pla = FreeCAD.Placement()
|
||||||
|
else:
|
||||||
|
info = getElementInfo(self.getAssembly().getPartGroup(),
|
||||||
|
self.getElementSubname(),offset=self.Object.Offset)
|
||||||
|
if not info or \
|
||||||
|
utils.isSamePlacement(info.PlacementOffset,obj.Placement):
|
||||||
|
return
|
||||||
|
pla = info.PlacementOffset
|
||||||
|
obj.setPropertyStatus('Placement','-Immutable')
|
||||||
|
obj.Placement = pla
|
||||||
|
obj.setPropertyStatus('Placement','Immutable')
|
||||||
|
|
||||||
def getAssembly(self):
|
def getAssembly(self):
|
||||||
return self.parent.parent
|
return self.parent.parent
|
||||||
|
@ -474,6 +497,8 @@ class AsmElement(AsmBase):
|
||||||
if not element:
|
if not element:
|
||||||
# try to search the element group for an existing element
|
# try to search the element group for an existing element
|
||||||
for e in elements.Group:
|
for e in elements.Group:
|
||||||
|
if not e.Offset.isIdentity():
|
||||||
|
continue
|
||||||
sub = logger.catch('',e.Proxy.getSubName)
|
sub = logger.catch('',e.Proxy.getSubName)
|
||||||
if sub == subname:
|
if sub == subname:
|
||||||
return e
|
return e
|
||||||
|
@ -543,7 +568,7 @@ class AsmElementSketch(AsmElement):
|
||||||
|
|
||||||
def linkSetup(self,obj):
|
def linkSetup(self,obj):
|
||||||
super(AsmElementSketch,self).linkSetup(obj)
|
super(AsmElementSketch,self).linkSetup(obj)
|
||||||
obj.setPropertyStatus('Placement','Hidden')
|
obj.setPropertyStatus('Placement',('Hidden','-Immutable'))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls,name,parent):
|
def create(cls,name,parent):
|
||||||
|
@ -588,9 +613,9 @@ class ViewProviderAsmElementSketch(ViewProviderAsmElement):
|
||||||
|
|
||||||
|
|
||||||
ElementInfo = namedtuple('AsmElementInfo', ('Parent','SubnameRef','Part',
|
ElementInfo = namedtuple('AsmElementInfo', ('Parent','SubnameRef','Part',
|
||||||
'PartName','Placement','Object','Subname','Shape'))
|
'PartName','Placement','Object','Subname','Shape','PlacementOffset'))
|
||||||
|
|
||||||
def getElementInfo(parent, subname, checkPlacement=False):
|
def getElementInfo(parent,subname,checkPlacement=False,shape=None,offset=None):
|
||||||
'''Return a named tuple containing the part object element information
|
'''Return a named tuple containing the part object element information
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -661,8 +686,8 @@ def getElementInfo(parent, subname, checkPlacement=False):
|
||||||
raise RuntimeError('Invalid sub-object {}, {}'.format(
|
raise RuntimeError('Invalid sub-object {}, {}'.format(
|
||||||
objName(parent), subnameRef))
|
objName(parent), subnameRef))
|
||||||
|
|
||||||
# For storing the shape of the element with proper transformation
|
transformShape = True if shape else False
|
||||||
shape = None
|
|
||||||
# For storing the placement of the movable part
|
# For storing the placement of the movable part
|
||||||
pla = None
|
pla = None
|
||||||
# For storing the actual geometry object of the part, in case 'part' is
|
# For storing the actual geometry object of the part, in case 'part' is
|
||||||
|
@ -690,6 +715,7 @@ def getElementInfo(parent, subname, checkPlacement=False):
|
||||||
# when ElementList has members, then the moveable Placement
|
# when ElementList has members, then the moveable Placement
|
||||||
# is a property of the array element. So we obtain the shape
|
# is a property of the array element. So we obtain the shape
|
||||||
# before 'Placement' by setting 'transform' set to False.
|
# before 'Placement' by setting 'transform' set to False.
|
||||||
|
if not shape:
|
||||||
shape=part[1].getSubObject(sub,transform=False)
|
shape=part[1].getSubObject(sub,transform=False)
|
||||||
pla = part[1].Placement
|
pla = part[1].Placement
|
||||||
obj = part[0].getLinkedObject(False)
|
obj = part[0].getLinkedObject(False)
|
||||||
|
@ -700,6 +726,7 @@ def getElementInfo(parent, subname, checkPlacement=False):
|
||||||
# is stored inside link object's PlacementList property. So,
|
# is stored inside link object's PlacementList property. So,
|
||||||
# the shape obtained below is already before 'Placement',
|
# the shape obtained below is already before 'Placement',
|
||||||
# i.e. no need to set 'transform' to False.
|
# i.e. no need to set 'transform' to False.
|
||||||
|
if not shape:
|
||||||
shape=part[1].getSubObject(sub)
|
shape=part[1].getSubObject(sub)
|
||||||
obj = part[1]
|
obj = part[1]
|
||||||
try:
|
try:
|
||||||
|
@ -718,7 +745,7 @@ def getElementInfo(parent, subname, checkPlacement=False):
|
||||||
|
|
||||||
subname = sub
|
subname = sub
|
||||||
|
|
||||||
if not shape:
|
if not obj:
|
||||||
# Here means, either the 'part' is an assembly or it is a non array
|
# Here means, either the 'part' is an assembly or it is a non array
|
||||||
# object. We trim the subname reference to be relative to the part
|
# object. We trim the subname reference to be relative to the part
|
||||||
# object. And obtain the shape before part's Placement by setting
|
# object. And obtain the shape before part's Placement by setting
|
||||||
|
@ -726,6 +753,7 @@ def getElementInfo(parent, subname, checkPlacement=False):
|
||||||
if checkPlacement and not hasattr(part,'Placement'):
|
if checkPlacement and not hasattr(part,'Placement'):
|
||||||
raise RuntimeError('part has no placement')
|
raise RuntimeError('part has no placement')
|
||||||
subname = '.'.join(names[1:])
|
subname = '.'.join(names[1:])
|
||||||
|
if not shape:
|
||||||
shape = utils.getElementShape((part,subname))
|
shape = utils.getElementShape((part,subname))
|
||||||
if not shape:
|
if not shape:
|
||||||
raise RuntimeError('cannot get geometry element from {}.{}'.format(
|
raise RuntimeError('cannot get geometry element from {}.{}'.format(
|
||||||
|
@ -734,6 +762,17 @@ def getElementInfo(parent, subname, checkPlacement=False):
|
||||||
obj = part.getLinkedObject(False)
|
obj = part.getLinkedObject(False)
|
||||||
partName = part.Name
|
partName = part.Name
|
||||||
|
|
||||||
|
if transformShape:
|
||||||
|
shape.transformShape(pla.toMatrix().inverse())
|
||||||
|
|
||||||
|
if not offset or offset.isIdentity():
|
||||||
|
plaOffset = FreeCAD.Placement()
|
||||||
|
else:
|
||||||
|
mat = utils.getElementPlacement(shape).toMatrix()
|
||||||
|
shape.transformShape(mat*offset.toMatrix()*mat.inverse())
|
||||||
|
mat = pla.toMatrix()*mat
|
||||||
|
plaOffset = FreeCAD.Placement(mat*offset.toMatrix()*mat.inverse())
|
||||||
|
|
||||||
return ElementInfo(Parent = parent,
|
return ElementInfo(Parent = parent,
|
||||||
SubnameRef = subnameRef,
|
SubnameRef = subnameRef,
|
||||||
Part = part,
|
Part = part,
|
||||||
|
@ -741,7 +780,8 @@ def getElementInfo(parent, subname, checkPlacement=False):
|
||||||
Placement = pla.copy(),
|
Placement = pla.copy(),
|
||||||
Object = obj,
|
Object = obj,
|
||||||
Subname = subname,
|
Subname = subname,
|
||||||
Shape = shape.copy())
|
Shape = shape,
|
||||||
|
PlacementOffset = plaOffset)
|
||||||
|
|
||||||
|
|
||||||
class AsmElementLink(AsmBase):
|
class AsmElementLink(AsmBase):
|
||||||
|
@ -753,7 +793,6 @@ class AsmElementLink(AsmBase):
|
||||||
def linkSetup(self,obj):
|
def linkSetup(self,obj):
|
||||||
super(AsmElementLink,self).linkSetup(obj)
|
super(AsmElementLink,self).linkSetup(obj)
|
||||||
obj.configLinkProperty('LinkedObject')
|
obj.configLinkProperty('LinkedObject')
|
||||||
# obj.setPropertyStatus('LinkedObject','Immutable')
|
|
||||||
obj.setPropertyStatus('LinkedObject','ReadOnly')
|
obj.setPropertyStatus('LinkedObject','ReadOnly')
|
||||||
|
|
||||||
def attach(self,obj):
|
def attach(self,obj):
|
||||||
|
@ -764,12 +803,13 @@ class AsmElementLink(AsmBase):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def execute(self,_obj):
|
def execute(self,_obj):
|
||||||
self.getInfo(True)
|
self.info = None
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def onChanged(self,_obj,prop):
|
def onChanged(self,_obj,prop):
|
||||||
if prop=='LinkedObject' and \
|
if not getattr(self,'parent',None) or FreeCAD.isRestoring():
|
||||||
getattr(self,'parent',None) and \
|
return
|
||||||
|
if prop not in _IgnoredProperties and \
|
||||||
not Constraint.isDisabled(self.parent.Object):
|
not Constraint.isDisabled(self.parent.Object):
|
||||||
Assembly.autoSolve()
|
Assembly.autoSolve()
|
||||||
|
|
||||||
|
@ -852,10 +892,11 @@ class AsmElementLink(AsmBase):
|
||||||
if ret:
|
if ret:
|
||||||
return ret
|
return ret
|
||||||
self.info = None
|
self.info = None
|
||||||
if not getattr(self,'Object',None):
|
obj = getattr(self,'Object',None)
|
||||||
|
if not obj:
|
||||||
return
|
return
|
||||||
self.info = getElementInfo(self.getAssembly().getPartGroup(),
|
self.info = getElementInfo(self.getAssembly().getPartGroup(),
|
||||||
self.getElementSubname())
|
self.getElementSubname(),shape=obj.getSubObject(''))
|
||||||
return self.info
|
return self.info
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -1352,7 +1393,7 @@ class Assembly(AsmGroup):
|
||||||
self.constraints = None
|
self.constraints = None
|
||||||
super(Assembly,self).__init__()
|
super(Assembly,self).__init__()
|
||||||
|
|
||||||
def getSubObjects(self,obj,reason):
|
def getSubObjects(self,_obj,reason):
|
||||||
partGroup = self.getPartGroup()
|
partGroup = self.getPartGroup()
|
||||||
return ['{}.{}'.format(partGroup.Name,name)
|
return ['{}.{}'.format(partGroup.Name,name)
|
||||||
for name in partGroup.getSubObjects(reason)]
|
for name in partGroup.getSubObjects(reason)]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user