diff --git a/assembly.py b/assembly.py index 6dd0080..d608b0a 100644 --- a/assembly.py +++ b/assembly.py @@ -2698,13 +2698,14 @@ BuildShapeNames = (BuildShapeNone,BuildShapeCompound, BuildShapeFuse,BuildShapeCut,BuildShapeCommon) class Assembly(AsmGroup): + _Busy = False _Timer = QtCore.QTimer() _TransID = 0 _PartMap = {} # maps part to assembly _PartArrayMap = {} # maps array part to assembly _ScheduleTimer = QtCore.QTimer() - _PendingRemove = [] _PendingReload = defaultdict(set) + _PendingSolve = False def __init__(self): self.parts = set() @@ -2812,6 +2813,8 @@ class Assembly(AsmGroup): @classmethod def autoSolve(cls,obj,prop,force=False): + if not force and cls._PendingSolve: + return if force or cls.canAutoSolve(): if not cls._Timer.isSingleShot(): cls._Timer.setSingleShot(True) @@ -2819,30 +2822,40 @@ class Assembly(AsmGroup): cls._TransID = FreeCAD.getActiveTransaction() logger.debug('auto solve scheduled on change of {}.{}', objName(obj),prop,frame=1) + if cls._Busy: + cls._PendingSolve = True + return cls._Timer.start(100) @classmethod def cancelAutoSolve(cls): logger.debug('cancel auto solve',frame=1) cls._Timer.stop() + cls._PendingSolve = False @classmethod def onSolverTimer(cls): - if not cls.canAutoSolve(): + canSolve = cls.canAutoSolve() + if cls._Busy or not canSolve: + cls._PendingSolve = canSolve return + + cls.cancelAutoSolve() + from . import solver trans = cls._TransID and cls._TransID==FreeCAD.getActiveTransaction() if not trans: cls._TransID = 0 FreeCAD.setActiveTransaction('Assembly auto recompute') + logger.debug('start solving...') if not logger.catch('solver exception when auto recompute', solver.solve, FreeCAD.ActiveDocument.Objects, True): if not trans: FreeCAD.closeActiveTransaction(True) - cls.cancelAutoSolve() else: if not trans: FreeCAD.closeActiveTransaction() + logger.debug('done solving') @classmethod def scheduleDelete(cls,doc,names): @@ -2866,12 +2879,24 @@ class Assembly(AsmGroup): if not cls._ScheduleTimer.isActive(): cls._ScheduleTimer.start(50) + @classmethod + def pauseSchedule(cls): + cls._Busy = True + cls._ScheduleTimer.stop() + if cls._Timer.isActive(): + cls._PendingSolve = True + cls._Timer.stop() + + @classmethod + def resumeSchedule(cls): + cls._Busy = False + cls.schedule() + if cls._PendingSolve: + cls._PendingSolve = False + cls._Timer.start(100) + @classmethod def onSchedule(cls): - 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: @@ -2882,17 +2907,6 @@ class Assembly(AsmGroup): obj.Freeze = False cls._PendingReload.clear() - for doc,names in cls._PendingRemove: - try: - for name in names: - try: - doc.removeObject(name) - except Exception: - pass - except Exception: - pass - cls._PendingRemove = [] - def onSolverChanged(self): for obj in self.getConstraintGroup().Group: # setup==True usually means we are restoring, so try to restore the diff --git a/mover.py b/mover.py index 4c4cc4c..d65f4b7 100644 --- a/mover.py +++ b/mover.py @@ -369,10 +369,10 @@ class AsmDocumentObserver: cls.closeMover() cls._quickMover = AsmQuickMover(info) - def slotNewDocument(self,_doc): + def slotCreatedDocument(self,_doc): self.closeMover() - def slotDeleteDocument(self,_doc): + def slotDeletedDocument(self,_doc): self.closeMover() def slotUndoDocument(self,_doc): @@ -383,12 +383,18 @@ class AsmDocumentObserver: def slotRedoDocument(self,_doc): self.slotUndoDocument(_doc) - def slotTransactionAbort(self,_doc): + def slotAbortTransaction(self,_doc): self.slotUndoDocument(_doc) def slotChangedObject(self,obj,prop): Assembly.checkPartChange(obj,prop) + def slotRecomputedDocument(self,_doc): + Assembly.resumeSchedule() + + def slotBeforeRecomputeDocument(self,_doc): + Assembly.pauseSchedule() + def quickMove(): ret = logger.catch('exception when moving part', getMovingElementInfo)