diff options
author | Nino van Hooff <ninovanhooff@gmail.com> | 2020-05-08 16:31:23 +0300 |
---|---|---|
committer | Nino van Hooff <ninovanhooff@gmail.com> | 2020-05-08 16:31:23 +0300 |
commit | 176919eee0ab397f0b9c151551dbef0b5fbb046e (patch) | |
tree | f826b03afa7e26124716ce224ea5c65a035ec2b8 /plugins/CuraEngineBackend | |
parent | 797d6ed4381f70fa91b623dbd7b9e1b61053e04d (diff) | |
parent | 2ecd30d6a9846bcec111043e7778f7df0ea461d6 (diff) |
Merge branch 'master' into doxygen_to_restructuredtext_comments
# Conflicts:
# plugins/CuraEngineBackend/CuraEngineBackend.py
# plugins/CuraEngineBackend/StartSliceJob.py
Diffstat (limited to 'plugins/CuraEngineBackend')
-rwxr-xr-x | plugins/CuraEngineBackend/CuraEngineBackend.py | 61 | ||||
-rw-r--r-- | plugins/CuraEngineBackend/StartSliceJob.py | 49 | ||||
-rw-r--r-- | plugins/CuraEngineBackend/plugin.json | 2 |
3 files changed, 64 insertions, 48 deletions
diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 4de10c5ed0..1c40052521 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -44,7 +44,7 @@ class CuraEngineBackend(QObject, Backend): def __init__(self) -> None: """Starts the back-end plug-in. - + This registers all the signal listeners and prepares for communication with the back-end in general. CuraEngineBackend is exposed to qml as well. @@ -181,7 +181,7 @@ class CuraEngineBackend(QObject, Backend): def close(self) -> None: """Terminate the engine process. - + This function should terminate the engine process. Called when closing the application. """ @@ -191,7 +191,7 @@ class CuraEngineBackend(QObject, Backend): def getEngineCommand(self) -> List[str]: """Get the command that is used to call the engine. - + This is useful for debugging and used to actually start the engine. :return: list of commands and args / parameters. """ @@ -300,7 +300,7 @@ class CuraEngineBackend(QObject, Backend): def _terminate(self) -> None: """Terminate the engine process. - + Start the engine process by calling _createSocket() """ self._slicing = False @@ -329,13 +329,13 @@ class CuraEngineBackend(QObject, Backend): def _onStartSliceCompleted(self, job: StartSliceJob) -> None: """Event handler to call when the job to initiate the slicing process is - + completed. - + When the start slice job is successfully completed, it will be happily slicing. This function handles any errors that may occur during the bootstrapping of a slice job. - + :param job: The start slice job that was just finished. """ if self._error_message: @@ -458,7 +458,7 @@ class CuraEngineBackend(QObject, Backend): def determineAutoSlicing(self) -> bool: """Determine enable or disable auto slicing. Return True for enable timer and False otherwise. - + It disables when: - preference auto slice is off - decorator isBlockSlicing is found (used in g-code reader) @@ -501,13 +501,13 @@ class CuraEngineBackend(QObject, Backend): def _onSceneChanged(self, source: SceneNode) -> None: """Listener for when the scene has changed. - + This should start a slice if the scene is now ready to slice. - + :param source: The scene node that was changed. """ - if not source.callDecoration("isSliceable"): + if not source.callDecoration("isSliceable") and source != self._scene.getRoot(): return # This case checks if the source node is a node that contains GCode. In this case the @@ -556,7 +556,7 @@ class CuraEngineBackend(QObject, Backend): def _onSocketError(self, error: Arcus.Error) -> None: """Called when an error occurs in the socket connection towards the engine. - + :param error: The exception that occurred. """ @@ -621,7 +621,7 @@ class CuraEngineBackend(QObject, Backend): def _onSettingChanged(self, instance: SettingInstance, property: str) -> None: """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. """ @@ -644,7 +644,7 @@ class CuraEngineBackend(QObject, Backend): def _onLayerMessage(self, message: Arcus.PythonMessage) -> None: """Called when a sliced layer data message is received from the engine. - + :param message: The protobuf message containing sliced layer data. """ @@ -652,7 +652,7 @@ class CuraEngineBackend(QObject, Backend): def _onOptimizedLayerMessage(self, message: Arcus.PythonMessage) -> None: """Called when an optimized sliced layer data message is received from the engine. - + :param message: The protobuf message containing sliced layer data. """ @@ -663,7 +663,7 @@ class CuraEngineBackend(QObject, Backend): def _onProgressMessage(self, message: Arcus.PythonMessage) -> None: """Called when a progress message is received from the engine. - + :param message: The protobuf message containing the slicing progress. """ @@ -685,7 +685,7 @@ class CuraEngineBackend(QObject, Backend): def _onSlicingFinishedMessage(self, message: Arcus.PythonMessage) -> None: """Called when the engine sends a message that slicing is finished. - + :param message: The protobuf message signalling that slicing is finished. """ @@ -732,7 +732,7 @@ class CuraEngineBackend(QObject, Backend): def _onGCodeLayerMessage(self, message: Arcus.PythonMessage) -> None: """Called when a g-code message is received from the engine. - + :param message: The protobuf message containing g-code, encoded as UTF-8. """ @@ -743,7 +743,7 @@ class CuraEngineBackend(QObject, Backend): def _onGCodePrefixMessage(self, message: Arcus.PythonMessage) -> None: """Called when a g-code prefix message is received from the engine. - + :param message: The protobuf message containing the g-code prefix, encoded as UTF-8. """ @@ -757,9 +757,12 @@ class CuraEngineBackend(QObject, Backend): """Creates a new socket connection.""" if not protocol_file: + if not self.getPluginId(): + Logger.error("Can't create socket before CuraEngineBackend plug-in is registered.") + return plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId()) if not plugin_path: - Logger.log("e", "Could not get plugin path!", self.getPluginId()) + Logger.error("Could not get plugin path!", self.getPluginId()) return protocol_file = os.path.abspath(os.path.join(plugin_path, "Cura.proto")) super()._createSocket(protocol_file) @@ -767,7 +770,7 @@ class CuraEngineBackend(QObject, Backend): def _onChanged(self, *args: Any, **kwargs: Any) -> None: """Called when anything has changed to the stuff that needs to be sliced. - + This indicates that we should probably re-slice soon. """ @@ -786,7 +789,7 @@ class CuraEngineBackend(QObject, Backend): def _onPrintTimeMaterialEstimates(self, message: Arcus.PythonMessage) -> None: """Called when a print time message is received from the engine. - + :param message: The protobuf message containing the print time per feature and material amount per extruder """ @@ -800,7 +803,7 @@ class CuraEngineBackend(QObject, Backend): def _parseMessagePrintTimes(self, message: Arcus.PythonMessage) -> Dict[str, float]: """Called for parsing message to retrieve estimated time per feature - + :param message: The protobuf message containing the print time per feature """ @@ -829,10 +832,10 @@ class CuraEngineBackend(QObject, Backend): def _onToolOperationStarted(self, tool: Tool) -> None: """Called when the user starts using some tool. - + When the user starts using a tool, we should pause slicing to prevent continuously slicing while the user is dragging some tool handle. - + :param tool: The tool that the user is using. """ @@ -845,9 +848,9 @@ class CuraEngineBackend(QObject, Backend): def _onToolOperationStopped(self, tool: Tool) -> None: """Called when the user stops using some tool. - + This indicates that we can safely start slicing again. - + :param tool: The tool that the user was using. """ @@ -886,7 +889,7 @@ class CuraEngineBackend(QObject, Backend): def _onBackendQuit(self) -> None: """Called when the back-end self-terminates. - + We should reset our state and start listening for new connections. """ @@ -935,7 +938,7 @@ class CuraEngineBackend(QObject, Backend): def disableTimer(self) -> None: """Disconnect slice function from timer. - + This means that slicing will not be triggered automatically """ if self._use_timer: diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index ef9aeef122..7cca3903f0 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -13,6 +13,8 @@ from UM.Job import Job from UM.Logger import Logger from UM.Scene.SceneNode import SceneNode from UM.Settings.ContainerStack import ContainerStack #For typing. +from UM.Settings.InstanceContainer import InstanceContainer +from UM.Settings.SettingDefinition import SettingDefinition from UM.Settings.SettingRelation import SettingRelation #For typing. from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator @@ -107,20 +109,32 @@ class StartSliceJob(Job): """returns true if it has errors, false otherwise.""" - if stack is None: - return False + top_of_stack = cast(InstanceContainer, stack.getTop()) # Cache for efficiency. + changed_setting_keys = top_of_stack.getAllKeys() - # if there are no per-object settings we don't need to check the other settings here - stack_top = stack.getTop() - if stack_top is None or not stack_top.getAllKeys(): - return False + # Add all relations to changed settings as well. + for key in top_of_stack.getAllKeys(): + instance = top_of_stack.getInstance(key) + if instance is None: + continue + self._addRelations(changed_setting_keys, instance.definition.relations) + Job.yieldThread() - for key in stack.getAllKeys(): - validation_state = stack.getProperty(key, "validationState") - if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid): - Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state) + for changed_setting_key in changed_setting_keys: + validation_state = stack.getProperty(changed_setting_key, "validationState") + + if validation_state is None: + definition = cast(SettingDefinition, stack.getSettingDefinition(changed_setting_key)) + validator_type = SettingDefinition.getValidatorForType(definition.type) + if validator_type: + validator = validator_type(changed_setting_key) + validation_state = validator(stack) + if validation_state in ( + ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid): + Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", changed_setting_key, validation_state) return True Job.yieldThread() + return False def run(self) -> None: @@ -330,7 +344,7 @@ class StartSliceJob(Job): def _buildReplacementTokens(self, stack: ContainerStack) -> Dict[str, Any]: """Creates a dictionary of tokens to replace in g-code pieces. - + This indicates what should be replaced in the start and end g-codes. :param stack: The stack to get the settings from to replace the tokens with. :return: A dictionary of replacement tokens to the values they should be replaced with. @@ -365,7 +379,7 @@ class StartSliceJob(Job): def _expandGcodeTokens(self, value: str, default_extruder_nr: int = -1) -> str: """Replace setting tokens in a piece of g-code. - + :param value: A piece of g-code to replace tokens in. :param default_extruder_nr: Stack nr to use when no stack nr is specified, defaults to the global stack """ @@ -417,7 +431,7 @@ class StartSliceJob(Job): def _buildGlobalSettingsMessage(self, stack: ContainerStack) -> None: """Sends all global settings to the engine. - + The settings are taken from the global stack. This does not include any per-extruder settings or per-object settings. """ @@ -457,10 +471,10 @@ class StartSliceJob(Job): def _buildGlobalInheritsStackMessage(self, stack: ContainerStack) -> None: """Sends for some settings which extruder they should fallback to if not set. - + This is only set for settings that have the limit_to_extruder property. - + :param stack: The global stack with all settings, from which to read the limit_to_extruder property. """ @@ -475,7 +489,7 @@ class StartSliceJob(Job): def _handlePerObjectSettings(self, node: CuraSceneNode, message: Arcus.PythonMessage): """Check if a node has per object settings and ensure that they are set correctly in the message - + :param node: Node to check. :param message: object_lists message to put the per object settings in """ @@ -517,7 +531,7 @@ class StartSliceJob(Job): def _addRelations(self, relations_set: Set[str], relations: List[SettingRelation]): """Recursive function to put all settings that require each other for value changes in a list - + :param relations_set: Set of keys of settings that are influenced :param relations: list of relation objects that need to be checked. """ @@ -528,4 +542,3 @@ class StartSliceJob(Job): relations_set.add(relation.target.key) self._addRelations(relations_set, relation.target.relations) - diff --git a/plugins/CuraEngineBackend/plugin.json b/plugins/CuraEngineBackend/plugin.json index 6817ad27be..2eee5deb61 100644 --- a/plugins/CuraEngineBackend/plugin.json +++ b/plugins/CuraEngineBackend/plugin.json @@ -2,7 +2,7 @@ "name": "CuraEngine Backend", "author": "Ultimaker B.V.", "description": "Provides the link to the CuraEngine slicing backend.", - "api": "7.1", + "api": "7.2.0", "version": "1.0.1", "i18n-catalog": "cura" } |