Fix auto-slicing upon value changes and error checks

CURA-4092

- Keep the error check finished signal.
- Restore the old way of triggering an auto-slicing which depends on a
  setting value change singal.
- Add a mechanism to make sure that if there is an error check, the
  auto-slicing will only be triggered after the check finishes.
This commit is contained in:
Lipu Fei 2017-07-27 09:03:04 +02:00
parent 021425ee06
commit d9d39c41df

View file

@ -76,9 +76,28 @@ class CuraEngineBackend(QObject, Backend):
self._scene = Application.getInstance().getController().getScene()
self._scene.sceneChanged.connect(self._onSceneChanged)
# trigger auto-slicing on error check finished
# Triggers for auto-slicing. Auto-slicing is triggered as follows:
# - auto-slicing is started with a timer
# - whenever there is a value change, we start the timer
# - sometimes an error check can get scheduled for a value change, in that case, we ONLY want to start the
# auto-slicing timer when that error check is finished
# If there is an error check, it will set the "_is_error_check_scheduled" flag, stop the auto-slicing timer,
# and only wait for the error check to be finished to start the auto-slicing timer again.
#
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()
Application.getInstance().stacksValidationFinished.connect(self._onStackErrorCheckFinished)
# A flag indicating if an error check was scheduled
# If so, we will stop the auto-slice timer and start upon the error check
self._is_error_check_scheduled = False
# Listeners for receiving messages from the back-end.
self._message_handlers["cura.proto.Layer"] = self._onLayerMessage
self._message_handlers["cura.proto.LayerOptimized"] = self._onOptimizedLayerMessage
@ -271,17 +290,16 @@ 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(global_container_stack.getId()))
extruders = list(ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()))
error_keys = []
for extruder in extruders:
error_keys.extend(extruder.getErrorKeys())
if not extruders:
error_keys = global_container_stack.getErrorKeys()
error_keys = self._global_container_stack.getErrorKeys()
error_labels = set()
for key in error_keys:
for stack in [global_container_stack] + extruders: #Search all container stacks for the definition of this setting. Some are only in an extruder stack.
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.
definitions = stack.getBottom().findDefinitions(key = key)
if definitions:
break #Found it! No need to continue search.
@ -420,7 +438,21 @@ 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.
self.needsSlicing()
self._onChanged()
elif property == "validationState":
if self._use_timer:
self._is_error_check_scheduled = True
self._change_timer.stop()
def _onStackErrorCheckFinished(self):
self._is_error_check_scheduled = False
self.needsSlicing()
self._onChanged()
@ -515,7 +547,12 @@ class CuraEngineBackend(QObject, Backend):
def _onChanged(self, *args, **kwargs):
self.needsSlicing()
if self._use_timer:
self._change_timer.start()
# if the error check is scheduled, wait for the error check finish signal to trigger auto-slice,
# otherwise business as usual
if self._is_error_check_scheduled:
self._change_timer.stop()
else:
self._change_timer.start()
## Called when the back-end connects to the front-end.
def _onBackendConnected(self):
@ -574,6 +611,44 @@ class CuraEngineBackend(QObject, Backend):
if self._process:
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