assembly: auto reload partial document on unfreeze

This commit is contained in:
Zheng, Lei 2018-08-06 00:39:00 +08:00
parent 1e5679fcf6
commit b678c360cf

View File

@ -1,5 +1,5 @@
import os import os
from collections import namedtuple from collections import namedtuple,defaultdict
import FreeCAD, FreeCADGui, Part import FreeCAD, FreeCADGui, Part
from PySide import QtCore, QtGui from PySide import QtCore, QtGui
from . import utils, gui from . import utils, gui
@ -285,7 +285,9 @@ class ViewProviderAsmPartGroup(ViewProviderAsmGroup):
return return
vobj.ChildViewProvider = 'PartGui::ViewProviderPartExt' vobj.ChildViewProvider = 'PartGui::ViewProviderPartExt'
cvp = vobj.ChildViewProvider cvp = vobj.ChildViewProvider
if not cvp.MapTransparency:
cvp.MapTransparency = True cvp.MapTransparency = True
if not cvp.MapFaceColor:
cvp.MapFaceColor = True cvp.MapFaceColor = True
cvp.ForceMapColors = True cvp.ForceMapColors = True
vobj.DefaultMode = mode vobj.DefaultMode = mode
@ -2308,6 +2310,7 @@ class Assembly(AsmGroup):
_PartArrayMap = {} # maps array part to assembly _PartArrayMap = {} # maps array part to assembly
_ScheduleTimer = QtCore.QTimer() _ScheduleTimer = QtCore.QTimer()
_PendingRemove = [] _PendingRemove = []
_PendingReload = defaultdict(set)
def __init__(self): def __init__(self):
self.parts = set() self.parts = set()
@ -2446,6 +2449,15 @@ class Assembly(AsmGroup):
pass pass
return return
cls._PendingRemove.append((doc,names)) cls._PendingRemove.append((doc,names))
cls.schedule()
@classmethod
def scheduleReload(cls,obj):
cls._PendingReload[obj.Document.Name].add(obj.Name)
cls.schedule()
@classmethod
def schedule(cls):
if not cls._ScheduleTimer.isSingleShot(): if not cls._ScheduleTimer.isSingleShot():
cls._ScheduleTimer.setSingleShot(True) cls._ScheduleTimer.setSingleShot(True)
cls._ScheduleTimer.timeout.connect(Assembly.onSchedule) cls._ScheduleTimer.timeout.connect(Assembly.onSchedule)
@ -2454,12 +2466,22 @@ class Assembly(AsmGroup):
@classmethod @classmethod
def onSchedule(cls): def onSchedule(cls):
pending = [] for doc in FreeCAD.listDocuments().values():
if doc.Recomputing:
cls._ScheduleTimer.start(50)
return
for name,onames in cls._PendingReload.items():
doc = FreeCADGui.reload(name)
if not doc:
break
for oname in onames:
obj = doc.getObject(oname)
if getattr(obj,'Freeze',None):
obj.Freeze = False
cls._PendingReload.clear()
for doc,names in cls._PendingRemove: for doc,names in cls._PendingRemove:
try: try:
if doc.Recomputing:
pending.append((doc,names))
continue
for name in names: for name in names:
try: try:
doc.removeObject(name) doc.removeObject(name)
@ -2467,9 +2489,7 @@ class Assembly(AsmGroup):
pass pass
except Exception: except Exception:
pass pass
cls._PendingRemove = pending cls._PendingRemove = []
if pending:
cls._ScheduleTimer.start(50)
def onSolverChanged(self): def onSolverChanged(self):
for obj in self.getConstraintGroup().Group: for obj in self.getConstraintGroup().Group:
@ -2566,11 +2586,8 @@ class Assembly(AsmGroup):
if not shapes: if not shapes:
raise RuntimeError('No shape found in parts') raise RuntimeError('No shape found in parts')
if len(shapes) == 1: if len(shapes) == 1:
shape = shapes[0] # hide shape placement, and get element mapping
# make sure the 'shape' has identity transform to prevent it from shape = Part.makeCompound(shapes)
# messing up with assembly's or partGroup's Placement
if not shape.Placement.isIdentity():
shape = Part.makeCompound(shape)
elif obj.BuildShape == BuildShapeFuse: elif obj.BuildShape == BuildShapeFuse:
shape = shapes[0].fuse(shapes[1:]) shape = shapes[0].fuse(shapes[1:])
elif obj.BuildShape == BuildShapeCut: elif obj.BuildShape == BuildShapeCut:
@ -2582,13 +2599,12 @@ class Assembly(AsmGroup):
if hasattr(partGroup,'Shape'): if hasattr(partGroup,'Shape'):
if obj.Freeze or obj.BuildShape!=BuildShapeCompound: if obj.Freeze or obj.BuildShape!=BuildShapeCompound:
shape.Tag = partGroup.ID
partGroup.Shape = shape partGroup.Shape = shape
shape.Tag = partGroup.ID
else: else:
partGroup.Shape = Part.Shape() partGroup.Shape = Part.Shape()
shape.Placement = obj.Placement shape.Placement = obj.Placement
shape.Tag = obj.ID
obj.Shape = shape obj.Shape = shape
def attach(self, obj): def attach(self, obj):
@ -2607,6 +2623,7 @@ class Assembly(AsmGroup):
obj.configLinkProperty('ColoredElements') obj.configLinkProperty('ColoredElements')
if not hasattr(obj,'Freeze'): if not hasattr(obj,'Freeze'):
obj.addProperty('App::PropertyBool','Freeze','Base','') obj.addProperty('App::PropertyBool','Freeze','Base','')
obj.setPropertyStatus('Freeze','PartialTrigger')
super(Assembly,self).linkSetup(obj) super(Assembly,self).linkSetup(obj)
obj.setPropertyStatus('Group','Output') obj.setPropertyStatus('Group','Output')
System.attach(obj) System.attach(obj)
@ -2639,6 +2656,9 @@ class Assembly(AsmGroup):
if prop == 'Freeze': if prop == 'Freeze':
if obj.Freeze == self.frozen: if obj.Freeze == self.frozen:
return return
if obj.Document.Partial:
Assembly.scheduleReload(obj)
return
self.upgrade() self.upgrade()
if obj.BuildShape==BuildShapeNone: if obj.BuildShape==BuildShapeNone:
self.buildShape() self.buildShape()