assembly: support label based element link
This commit is contained in:
parent
15babab61d
commit
1960144ef2
378
assembly.py
378
assembly.py
|
@ -63,8 +63,6 @@ class AsmBase(object):
|
|||
def onDocumentRestored(self, obj):
|
||||
self.linkSetup(obj)
|
||||
|
||||
def onChanged(self,_obj,_prop):
|
||||
pass
|
||||
|
||||
class ViewProviderAsmBase(object):
|
||||
def __init__(self,vobj):
|
||||
|
@ -150,6 +148,9 @@ class AsmPartGroup(AsmGroup):
|
|||
self.parent = getProxy(parent,Assembly)
|
||||
super(AsmPartGroup,self).__init__()
|
||||
|
||||
def getAssembly(self):
|
||||
return self.parent
|
||||
|
||||
def groupSetup(self):
|
||||
pass
|
||||
|
||||
|
@ -183,6 +184,7 @@ class ViewProviderAsmPartGroup(ViewProviderAsmGroup):
|
|||
|
||||
class AsmElement(AsmBase):
|
||||
def __init__(self,parent):
|
||||
self._initializing = True
|
||||
self.shape = None
|
||||
self.parent = getProxy(parent,AsmElementGroup)
|
||||
super(AsmElement,self).__init__()
|
||||
|
@ -200,6 +202,21 @@ class AsmElement(AsmBase):
|
|||
def canLinkProperties(self,_obj):
|
||||
return False
|
||||
|
||||
def allowDuplicateLabel(self,_obj):
|
||||
return True
|
||||
|
||||
def onBeforeChangeLabel(self,obj,label):
|
||||
parent = getattr(self,'parent',None)
|
||||
if parent and not getattr(self,'_initializing',False):
|
||||
return parent.onChildLabelChange(obj,label)
|
||||
|
||||
def onChanged(self,_obj,prop):
|
||||
parent = getattr(self,'parent',None)
|
||||
if parent and \
|
||||
not getattr(self,'_initializing',False) and \
|
||||
prop=='Label':
|
||||
parent.Object.cacheChildLabel()
|
||||
|
||||
def execute(self,_obj):
|
||||
self.getShape(True)
|
||||
return False
|
||||
|
@ -229,35 +246,46 @@ class AsmElement(AsmBase):
|
|||
objName(self.Object)))
|
||||
return link[1]
|
||||
|
||||
def setLink(self,owner,subname):
|
||||
# subname must be relative to the part group object of the parent
|
||||
# assembly
|
||||
def getElementSubname(self):
|
||||
'''
|
||||
Resolve the geometry element link relative to the parent assembly's part
|
||||
group
|
||||
'''
|
||||
|
||||
# check old linked object for auto re-label
|
||||
obj = self.Object
|
||||
linked = obj.getLinkedObject(False)
|
||||
if linked and linked!=obj:
|
||||
label = '{}_{}_Element'.format(linked.Label,self.getSubElement())
|
||||
else:
|
||||
label = ''
|
||||
subname = self.getSubName()
|
||||
obj = self.Object.getLinkedObject(False)
|
||||
if not obj or obj == self.Object:
|
||||
raise RuntimeError('Borken element link')
|
||||
if not isTypeOf(obj,AsmElement):
|
||||
# If not pointing to another element, then assume we are directly
|
||||
# pointing to the geometry element, just return as it is, which is a
|
||||
# subname relative to the parent assembly part group
|
||||
return subname
|
||||
|
||||
obj.setLink(owner,subname)
|
||||
childElement = obj.Proxy
|
||||
|
||||
if obj.Label==obj.Name or obj.Label.startswith(label):
|
||||
linked = obj.getLinkedObject(False)
|
||||
if linked and linked!=obj:
|
||||
obj.Label = '{}_{}_Element'.format(
|
||||
linked.Label,self.getSubElement())
|
||||
else:
|
||||
obj.Label = obj.Name
|
||||
# If pointing to another element in the child assembly, first pop two
|
||||
# names in the subname reference, i.e. element label and element group
|
||||
# name
|
||||
idx = subname.rfind('.',0,subname.rfind('.',0,-1))
|
||||
subname = subname[:idx+1]
|
||||
|
||||
Selection = namedtuple('AsmElementSelection',
|
||||
('Assembly','Element','Subname'))
|
||||
# append the child assembly part group name, and recursively call into
|
||||
# child element
|
||||
return subname+childElement.getAssembly().getPartGroup().Name+'.'+\
|
||||
childElement.getElementSubname()
|
||||
|
||||
# Element: optional, if none, then a new element will be created if no
|
||||
# pre-existing. Or else, it shall be the element to be amended
|
||||
# Group: the immediate child object of an assembly (i.e. ConstraintGroup,
|
||||
# ElementGroup, or PartGroup)
|
||||
# Subname: the subname reference realtive to 'Group'
|
||||
Selection = namedtuple('AsmElementSelection',('Element','Group','Subname'))
|
||||
|
||||
@staticmethod
|
||||
def getSelection():
|
||||
'''
|
||||
Parse Gui.Selection for making a element
|
||||
Parse Gui.Selection for making an element
|
||||
|
||||
If there is only one selection, then the selection must refer to a sub
|
||||
element of some part object of an assembly. We shall create a new
|
||||
|
@ -314,32 +342,102 @@ class AsmElement(AsmBase):
|
|||
if not isTypeOf(element,AsmElement):
|
||||
raise RuntimeError('The second selection must be an element')
|
||||
|
||||
return AsmElement.Selection(Assembly = link.Assembly,
|
||||
Element = element,
|
||||
Subname = link.Subname+subElement)
|
||||
return AsmElement.Selection(Element=element, Group=link.Object,
|
||||
Subname=link.Subname+subElement)
|
||||
|
||||
@staticmethod
|
||||
def make(selection=None,name='Element'):
|
||||
'''Add/get/modify an element with the given selected object'''
|
||||
if not selection:
|
||||
selection = AsmElement.getSelection()
|
||||
if not selection.Subname or selection.Subname[-1]=='.':
|
||||
raise RuntimeError('Subname must refer to a sub-element')
|
||||
assembly = getProxy(selection.Assembly,Assembly)
|
||||
|
||||
group = selection.Group
|
||||
subname = selection.Subname
|
||||
|
||||
if isTypeOf(group,AsmElementGroup):
|
||||
# if the selected object is an element of the owner assembly, simply
|
||||
# return that element
|
||||
element = group.getSubObject(subname,1)
|
||||
if not isTypeOf(element,AsmElement):
|
||||
raise RuntimeError('Invalid element reference {}.{}'.format(
|
||||
group.Name,subname))
|
||||
return element
|
||||
|
||||
if isTypeOf(group,AsmConstraintGroup):
|
||||
# if the selected object is an element link of a constraint of the
|
||||
# current assembly, then try to import its linked element if it is
|
||||
# not already imported
|
||||
link = group.getSubObject(subname,1)
|
||||
if not isTypeOf(link,AsmElementLink):
|
||||
raise RuntimeError('Invalid element link {}.{}'.format(
|
||||
group.Name,subname))
|
||||
ref = link.LinkedObject
|
||||
if not isinstance(ref,tuple):
|
||||
raise RuntimeError('Invalid link reference {}.{}'.format(
|
||||
group.Name,subname))
|
||||
if ref[1][0]=='$':
|
||||
# this means the element is in the current assembly already
|
||||
element = link.getLinkedObject(False)
|
||||
if not isTypeOf(element,AsmElement):
|
||||
raise RuntimeError('broken element link {}.{}'.format(
|
||||
group.Name,subname))
|
||||
return element
|
||||
|
||||
subname = ref[1]
|
||||
group = group.getAssembly().getPartGroup()
|
||||
|
||||
elif isTypeOf(group,AsmPartGroup):
|
||||
# If the selection come from the part group, first check for any
|
||||
# intermediate child assembly
|
||||
ret = Assembly.find(group,subname)
|
||||
if not ret:
|
||||
# If no child assembly in 'subname', simply assign the link as
|
||||
# it is, after making sure it is referencing an sub-element
|
||||
if not subname or subname[-1]=='.':
|
||||
raise RuntimeError(
|
||||
'Element must reference a geometry element')
|
||||
else:
|
||||
# In case there are intermediate assembly inside subname, we'll
|
||||
# recursively export the element in child assemblies first, and
|
||||
# then import that element to the current assembly.
|
||||
sel = AsmElement.Selection(
|
||||
Element=None, Group=ret.Object, Subname=ret.Subname)
|
||||
element = AsmElement.make(sel)
|
||||
|
||||
# now generate the subname reference
|
||||
|
||||
# This give us reference to child assembly's immediate child
|
||||
# without trailing dot.
|
||||
prefix = subname[:len(subname)-len(ret.Subname)-1]
|
||||
|
||||
# Pop the immediate child name, and replace it with child
|
||||
# assembly's element group name
|
||||
prefix = prefix[:prefix.rfind('.')+1] + \
|
||||
ret.Assembly.Proxy.getElementGroup().Name
|
||||
|
||||
subname = '{}.${}.'.format(prefix,element.Label)
|
||||
|
||||
else:
|
||||
raise RuntimeError('Invalid selection {}.{}'.format(
|
||||
group.Name,subname))
|
||||
|
||||
element = selection.Element
|
||||
if not element:
|
||||
elements = assembly.getElementGroup()
|
||||
elements = group.Proxy.getAssembly().getElementGroup()
|
||||
# try to search the element group for an existing element
|
||||
for e in elements.Group:
|
||||
sub = logger.catch('',e.Proxy.getSubName)
|
||||
if sub == selection.Subname:
|
||||
if sub == subname:
|
||||
return e
|
||||
element = elements.Document.addObject("App::FeaturePython",
|
||||
name,AsmElement(elements),None,True)
|
||||
ViewProviderAsmElement(element.ViewObject)
|
||||
elements.setLink({-1:element})
|
||||
elements.setElementVisible(element.Name,False)
|
||||
element.Proxy._initializing = False
|
||||
elements.cacheChildLabel()
|
||||
|
||||
getProxy(element,AsmElement).setLink(
|
||||
assembly.getPartGroup(),selection.Subname)
|
||||
element.setLink(group,subname)
|
||||
return element
|
||||
|
||||
|
||||
|
@ -357,17 +455,14 @@ class ViewProviderAsmElement(ViewProviderAsmOnTop):
|
|||
return (60.0/255.0,1.0,1.0)
|
||||
|
||||
def canDropObjectEx(self,_obj,owner,subname):
|
||||
# check if is dropping a sub-element
|
||||
if not subname or subname[-1]=='.':
|
||||
if not subname:
|
||||
return False
|
||||
proxy = self.ViewObject.Object.Proxy
|
||||
return proxy.getAssembly().getPartGroup()==owner
|
||||
|
||||
def dropObjectEx(self,vobj,_obj,_owner,subname):
|
||||
obj = vobj.Object
|
||||
AsmElement.make(AsmElement.Selection(
|
||||
Assembly=obj.Proxy.getAssembly().Object,
|
||||
Element=obj, Subname=subname))
|
||||
def dropObjectEx(self,vobj,_obj,owner,subname):
|
||||
AsmElement.make(AsmElement.Selection(Element=vobj.Object,
|
||||
Group=owner, Subname=subname))
|
||||
|
||||
|
||||
PartInfo = namedtuple('AsmPartInfo', ('Parent','SubnameRef','Part',
|
||||
|
@ -543,103 +638,64 @@ class AsmElementLink(AsmBase):
|
|||
self.getInfo(True)
|
||||
return False
|
||||
|
||||
def getElement(self):
|
||||
linked = self.Object.getLinkedObject(False)
|
||||
if not linked:
|
||||
raise RuntimeError('Element link broken')
|
||||
if not isTypeOf(linked,AsmElement):
|
||||
raise RuntimeError('Invalid element type')
|
||||
return linked.Proxy
|
||||
|
||||
def getAssembly(self):
|
||||
return self.parent.parent.parent
|
||||
|
||||
def getSubName(self):
|
||||
link = self.Object.LinkedObject
|
||||
if not isinstance(link,tuple):
|
||||
raise RuntimeError('Invalid element link "{}"'.format(
|
||||
objName(self.Object)))
|
||||
return link[1]
|
||||
|
||||
def getElementSubname(self):
|
||||
'''Resolve element link subname
|
||||
'Resolve element link subname'
|
||||
|
||||
AsmElementLink links to elements of a constraint. It always link to an
|
||||
AsmElement object belonging to the same parent assembly. AsmElement is
|
||||
also a link, which links to an arbitrarily nested part object. This
|
||||
function is for resolving the AsmElementLink's subname reference to the
|
||||
actual part object subname reference relative to the parent assembly's
|
||||
part group
|
||||
'''
|
||||
element = self.getElement()
|
||||
# AsmElementLink is used by constraint to link to a geometry link. It
|
||||
# does so by indirectly linking to an AsmElement object belonging to
|
||||
# the same parent assembly. AsmElement is also a link, which again
|
||||
# links to another AsmElement of a child assembly or the actual
|
||||
# geometry element of a child feature. This function is for resolving
|
||||
# the AsmElementLink's subname reference to the actual part object
|
||||
# subname reference relative to the parent assembly's part group
|
||||
|
||||
linked = self.Object.getLinkedObject(False)
|
||||
if not linked or linked == self.Object:
|
||||
raise RuntimeError('Element link broken')
|
||||
element = getProxy(linked,AsmElement)
|
||||
assembly = element.getAssembly()
|
||||
if assembly == self.getAssembly():
|
||||
return element.getSubName()
|
||||
# pop two names from back (i.e. element group, element)
|
||||
subname = self.getSubName()
|
||||
sub = subname.split('.')[:-3]
|
||||
sub = '.'.join(sub) + '.' + assembly.getPartGroup().Name + \
|
||||
'.' + element.getSubName()
|
||||
logger.debug('shape subname {} -> {}'.format(subname,sub))
|
||||
return sub
|
||||
return element.getElementSubname()
|
||||
|
||||
def prepareLink(self,owner,subname,checkOnly=False):
|
||||
if not owner or not subname:
|
||||
raise RuntimeError('no owner or subname')
|
||||
assembly = self.getAssembly()
|
||||
sobj = owner.getSubObject(subname,1)
|
||||
if not sobj:
|
||||
raise RuntimeError('invalid element link {} broken: {}'.format(
|
||||
objName(owner),subname))
|
||||
if isTypeOf(sobj,AsmElementLink):
|
||||
# if it points to another AsElementLink that belongs the same
|
||||
# assembly, simply return the same link
|
||||
if sobj.Proxy.getAssembly() == assembly:
|
||||
return sobj.LinkedObject
|
||||
# If it is from another assembly (i.e. a nested assembly), convert
|
||||
# the subname reference by poping three names (constraint group,
|
||||
# constraint, element link) from the back, and then append with the
|
||||
# element link's own subname reference
|
||||
sub = subname.split('.')[:-4]
|
||||
sub = '.'.join(subname)+'.'+sobj.Proxy.getSubName()
|
||||
logger.debug('convert element link {} -> {}'.format(subname,sub))
|
||||
return (owner,sub)
|
||||
|
||||
if isTypeOf(sobj,AsmElement):
|
||||
return (owner,subname)
|
||||
|
||||
# try to see if the reference comes from some nested assembly
|
||||
ret = assembly.find(owner,subname,recursive=True)
|
||||
if not ret:
|
||||
# It is from a non assembly child part, then use our own element
|
||||
# group as the holder for elements
|
||||
ret = [Assembly.Info(assembly.Object,owner,subname)]
|
||||
|
||||
if not isTypeOf(ret[-1].Object,AsmPartGroup):
|
||||
raise RuntimeError('Invalid element link ' + subname)
|
||||
|
||||
if checkOnly:
|
||||
if not ret[-1].Subname or ret[-1].Subname[-1]=='.':
|
||||
raise RuntimeError('Subname must refer to a sub-element')
|
||||
return True
|
||||
|
||||
# call AsmElement.make to either create a new element, or an existing
|
||||
# element if there is one
|
||||
element = AsmElement.make(AsmElement.Selection(
|
||||
ret[-1].Assembly,None,ret[-1].Subname))
|
||||
if ret[-1].Assembly == assembly.Object:
|
||||
return (assembly.getElementGroup(),element.Name+'.')
|
||||
|
||||
elementSub = ret[-1].Object.Name + '.' + ret[-1].Subname
|
||||
sub = subname[:-(len(elementSub)+1)] + '.' + \
|
||||
ret[-1].Assembly.Proxy.getElementGroup().Name + '.' + \
|
||||
element.Name + '.'
|
||||
logger.debug('generate new element {} -> {}'.format(subname,sub))
|
||||
return (owner,sub)
|
||||
# The reference stored inside this ElementLink. We need the sub assembly
|
||||
# name, which is the name before the first dot. This name may be
|
||||
# different from the actual assembly object's name, in case where the
|
||||
# assembly is accessed through a link
|
||||
ref = self.Object.LinkedObject[1]
|
||||
return '{}.{}.{}'.format(ref[0:ref.find('.')],
|
||||
assembly.getPartGroup().Name, element.getElementSubname())
|
||||
|
||||
def setLink(self,owner,subname):
|
||||
obj = self.Object
|
||||
owner,subname = self.prepareLink(owner,subname)
|
||||
# check if there is any sub assembly in the reference
|
||||
ret = Assembly.find(owner,subname)
|
||||
if not ret:
|
||||
# if not, add/get an element in our own element group
|
||||
sel = AsmElement.Selection(Element=None, Group=owner,
|
||||
Subname=subname)
|
||||
element = AsmElement.make(sel)
|
||||
owner = element.Proxy.parent.Object
|
||||
subname = '${}.'.format(element.Label)
|
||||
else:
|
||||
# if so, add/get an element from the sub assembly
|
||||
sel = AsmElement.Selection(Element=None, Group=ret.Object,
|
||||
Subname=ret.Subname)
|
||||
element = AsmElement.make(sel)
|
||||
owner = owner.Proxy.getAssembly().getPartGroup()
|
||||
|
||||
# This give us reference to child assembly's immediate child
|
||||
# without trailing dot.
|
||||
prefix = subname[:len(subname)-len(ret.Subname)-1]
|
||||
|
||||
# Pop the immediate child name, and replace it with child
|
||||
# assembly's element group name
|
||||
prefix = prefix[:prefix.rfind('.')+1] + \
|
||||
ret.Assembly.Proxy.getElementGroup().Name
|
||||
|
||||
subname = '{}.${}.'.format(prefix, element.Label)
|
||||
|
||||
for sibling in self.parent.Object.Group:
|
||||
if sibling == self.Object:
|
||||
continue
|
||||
|
@ -648,15 +704,7 @@ class AsmElementLink(AsmBase):
|
|||
linked[0]==owner and linked[1]==subname:
|
||||
raise RuntimeError('duplicate element link {} in constraint '
|
||||
'{}'.format(objName(sibling),objName(self.parent.Object)))
|
||||
obj.setLink(owner,subname)
|
||||
linked = obj.getLinkedObject(False)
|
||||
if linked and linked!=obj:
|
||||
label = linked.Label.split('_')
|
||||
if label[-1].startswith('Element'):
|
||||
label[-1] = 'Link'
|
||||
obj.Label = '_'.join(label)
|
||||
else:
|
||||
obj.Label = obj.Name
|
||||
self.Object.setLink(owner,subname)
|
||||
|
||||
def getInfo(self,refresh=False):
|
||||
if not refresh:
|
||||
|
@ -694,12 +742,12 @@ class AsmElementLink(AsmBase):
|
|||
|
||||
@staticmethod
|
||||
def make(info,name='ElementLink'):
|
||||
element = info.Constraint.Document.addObject("App::FeaturePython",
|
||||
link = info.Constraint.Document.addObject("App::FeaturePython",
|
||||
name,AsmElementLink(info.Constraint),None,True)
|
||||
ViewProviderAsmElementLink(element.ViewObject)
|
||||
info.Constraint.setLink({-1:element})
|
||||
element.Proxy.setLink(info.Owner,info.Subname)
|
||||
return element
|
||||
ViewProviderAsmElementLink(link.ViewObject)
|
||||
info.Constraint.setLink({-1:link})
|
||||
link.Proxy.setLink(info.Owner,info.Subname)
|
||||
return link
|
||||
|
||||
def setPlacement(part,pla,undoDocs,undoName=None):
|
||||
AsmElementLink.setPlacement(part,pla,undoDocs,undoName)
|
||||
|
@ -755,7 +803,6 @@ class AsmConstraint(AsmGroup):
|
|||
System.getTypeName(assembly)))
|
||||
|
||||
def onChanged(self,obj,prop):
|
||||
super(AsmConstraint,self).onChanged(obj,prop)
|
||||
if Constraint.onChanged(obj,prop):
|
||||
obj.recompute()
|
||||
|
||||
|
@ -945,7 +992,7 @@ class AsmConstraint(AsmGroup):
|
|||
raise
|
||||
|
||||
|
||||
class ViewProviderAsmConstraint(ViewProviderAsmGroupOnTop):
|
||||
class ViewProviderAsmConstraint(ViewProviderAsmGroup):
|
||||
def __init__(self,vobj):
|
||||
vobj.OverrideMaterial = True
|
||||
vobj.ShapeMaterial.DiffuseColor = self.getDefaultColor()
|
||||
|
@ -1002,6 +1049,9 @@ class AsmConstraintGroup(AsmGroup):
|
|||
self.parent = getProxy(parent,Assembly)
|
||||
super(AsmConstraintGroup,self).__init__()
|
||||
|
||||
def getAssembly(self):
|
||||
return self.parent
|
||||
|
||||
def linkSetup(self,obj):
|
||||
super(AsmConstraintGroup,self).linkSetup(obj)
|
||||
obj.setPropertyStatus('VisibilityList','Output')
|
||||
|
@ -1037,10 +1087,29 @@ class AsmElementGroup(AsmGroup):
|
|||
obj.setPropertyStatus('VisibilityList','Output')
|
||||
for o in obj.Group:
|
||||
getProxy(o,AsmElement).parent = self
|
||||
obj.cacheChildLabel()
|
||||
|
||||
def getAssembly(self):
|
||||
return self.parent
|
||||
|
||||
def onChildLabelChange(self,obj,label):
|
||||
names = set()
|
||||
for o in self.Object.Group:
|
||||
if o != obj:
|
||||
names.add(o.Name)
|
||||
if label not in names:
|
||||
return
|
||||
for i,c in enumerate(reversed(label)):
|
||||
if not c.isdigit():
|
||||
label = label[:i+1]
|
||||
break;
|
||||
i=0
|
||||
while True:
|
||||
i=i+1;
|
||||
newLabel = '{}{03d}'.format(label,i);
|
||||
if newLabel!=obj.Label and newLabel not in names:
|
||||
return newLabel
|
||||
|
||||
@staticmethod
|
||||
def make(parent,name='Elements'):
|
||||
obj = parent.Document.addObject("App::FeaturePython",name,
|
||||
|
@ -1057,16 +1126,14 @@ class ViewProviderAsmElementGroup(ViewProviderAsmGroupOnTop):
|
|||
return False
|
||||
|
||||
def canDropObjectEx(self,_obj,owner,subname):
|
||||
# check if is dropping a sub-element
|
||||
if not subname or subname[-1]=='.':
|
||||
if not subname:
|
||||
return False
|
||||
proxy = self.ViewObject.Object.Proxy
|
||||
return proxy.getAssembly().getPartGroup()==owner
|
||||
|
||||
def dropObjectEx(self,vobj,_obj,_owner,subname):
|
||||
def dropObjectEx(self,_vobj,_obj,owner,subname):
|
||||
AsmElement.make(AsmElement.Selection(
|
||||
Assembly=vobj.Object.Proxy.getAssembly().Object,
|
||||
Element=None, Subname=subname))
|
||||
Element=None, Group=owner, Subname=subname))
|
||||
|
||||
|
||||
BuildShapeNone = 'None'
|
||||
|
@ -1163,7 +1230,6 @@ class Assembly(AsmGroup):
|
|||
obj.setPropertyStatus('Shape','Transient')
|
||||
return
|
||||
System.onChanged(obj,prop)
|
||||
super(Assembly,self).onChanged(obj,prop)
|
||||
|
||||
def getConstraintGroup(self, create=False):
|
||||
obj = self.Object
|
||||
|
@ -1401,6 +1467,8 @@ class AsmMovingPart(object):
|
|||
# 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()
|
||||
|
||||
hasBound = True
|
||||
if not utils.isVertex(shape):
|
||||
self.bbox = shape.BoundBox
|
||||
else:
|
||||
|
@ -1411,8 +1479,15 @@ class AsmMovingPart(object):
|
|||
logger.warn('empty bounding box of part {}'.format(
|
||||
info.PartName))
|
||||
self.bbox = FreeCAD.BoundBox(0,0,0,5,5,5)
|
||||
hasBound = False
|
||||
|
||||
pla = FreeCAD.Placement(utils.getElementPos(shape),rot)
|
||||
pos = utils.getElementPos(shape)
|
||||
if not pos:
|
||||
if hasBound:
|
||||
pos = self.bbox.Center
|
||||
else:
|
||||
pos = shape.Placement.Base
|
||||
pla = FreeCAD.Placement(pos,rot)
|
||||
|
||||
self.offset = pla.copy()
|
||||
self.offsetInv = pla.inverse()
|
||||
|
@ -1590,6 +1665,9 @@ class ViewProviderAssembly(ViewProviderAsmGroup):
|
|||
partGroup,owner,subname = info
|
||||
return partGroup.canDropObject(obj,owner,subname)
|
||||
|
||||
def canDragAndDropObject(self,_obj):
|
||||
return True
|
||||
|
||||
def dropObjectEx(self,_vobj,obj,owner,subname):
|
||||
info = self._convertSubname(owner,subname)
|
||||
if not info:
|
||||
|
|
Loading…
Reference in New Issue
Block a user