Trigger auto-slice based on stackValidation instead of stack/setting changes

CURA-4084

Stack error checks are scheduled with a delay, and when a container is
changed (e.g. Quality), the auto-slice may get triggered before the
error check is done. Because the error check result is cached, the
auto-slicing will use the previous result instead of new. So, the
auto-slicing should be triggered when a stack validation is finished
instead of when a stack/setting gets changed.
This commit is contained in:
Lipu Fei 2017-07-26 14:00:02 +02:00
parent b08c4cd1dc
commit 93731b8d1f
2 changed files with 11 additions and 56 deletions

View file

@ -115,6 +115,7 @@ class MachineManager(QObject):
activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed.
activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed
stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed
stacksValidationFinished = pyqtSignal() # Emitted whenever a validation is finished
blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly
@ -305,6 +306,7 @@ class MachineManager(QObject):
self._stacks_have_errors = self._checkStacksHaveErrors()
if old_stacks_have_errors != self._stacks_have_errors:
self.stacksValidationChanged.emit()
self.stacksValidationFinished.emit()
def _onActiveExtruderStackChanged(self):
self.blurSettings.emit() # Ensure no-one has focus.

View file

@ -76,14 +76,8 @@ class CuraEngineBackend(QObject, Backend):
self._scene = Application.getInstance().getController().getScene()
self._scene.sceneChanged.connect(self._onSceneChanged)
# Triggers for when to (re)start slicing:
self._global_container_stack = None
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
self._onGlobalStackChanged()
self._active_extruder_stack = None
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
self._onActiveExtruderChanged()
# trigger auto-slicing on error check finished
Application.getInstance().getMachineManager().stacksValidationFinished.connect(self._onStackErrorCheckFinished)
# Listeners for receiving messages from the back-end.
self._message_handlers["cura.proto.Layer"] = self._onLayerMessage
@ -277,16 +271,17 @@ class CuraEngineBackend(QObject, Backend):
return
if job.getResult() == StartSliceJob.StartJobResult.SettingError:
global_container_stack = Application.getInstance().getGlobalContainerStack()
if Application.getInstance().platformActivity:
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()))
error_keys = []
for extruder in extruders:
error_keys.extend(extruder.getErrorKeys())
if not extruders:
error_keys = self._global_container_stack.getErrorKeys()
error_keys = global_container_stack.getErrorKeys()
error_labels = set()
for key in error_keys:
for stack in [self._global_container_stack] + extruders: #Search all container stacks for the definition of this setting. Some are only in an extruder stack.
for stack in [global_container_stack] + extruders: #Search all container stacks for the definition of this setting. Some are only in an extruder stack.
definitions = stack.getBottom().findDefinitions(key = key)
if definitions:
break #Found it! No need to continue search.
@ -425,12 +420,7 @@ class CuraEngineBackend(QObject, Backend):
# With manually having to slice, we want to clear the old invalid layer data.
self._clearLayerData()
## A setting has changed, so check if we must reslice.
#
# \param instance The setting instance that has changed.
# \param property The property of the setting instance that has changed.
def _onSettingChanged(self, instance, property):
if property == "value": # Only reslice if the value has changed.
def _onStackErrorCheckFinished(self):
self.needsSlicing()
self._onChanged()
@ -585,43 +575,6 @@ class CuraEngineBackend(QObject, Backend):
Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait())
self._process = None
## Called when the global container stack changes
def _onGlobalStackChanged(self):
if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onSettingChanged)
self._global_container_stack.containersChanged.disconnect(self._onChanged)
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
if extruders:
for extruder in extruders:
extruder.propertyChanged.disconnect(self._onSettingChanged)
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
if self._global_container_stack:
self._global_container_stack.propertyChanged.connect(self._onSettingChanged) # Note: Only starts slicing when the value changed.
self._global_container_stack.containersChanged.connect(self._onChanged)
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
if extruders:
for extruder in extruders:
extruder.propertyChanged.connect(self._onSettingChanged)
self._onActiveExtruderChanged()
self._onChanged()
def _onActiveExtruderChanged(self):
if self._global_container_stack:
# Connect all extruders of the active machine. This might cause a few connects that have already happend,
# but that shouldn't cause issues as only new / unique connections are added.
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
if extruders:
for extruder in extruders:
extruder.propertyChanged.connect(self._onSettingChanged)
if self._active_extruder_stack:
self._active_extruder_stack.containersChanged.disconnect(self._onChanged)
self._active_extruder_stack = ExtruderManager.getInstance().getActiveExtruderStack()
if self._active_extruder_stack:
self._active_extruder_stack.containersChanged.connect(self._onChanged)
def _onProcessLayersFinished(self, job):
self._process_layers_job = None