|
@@ -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
|