Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Ultimaker/Cura.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNino van Hooff <ninovanhooff@gmail.com>2020-05-08 16:23:51 +0300
committerNino van Hooff <ninovanhooff@gmail.com>2020-05-08 16:23:51 +0300
commit797d6ed4381f70fa91b623dbd7b9e1b61053e04d (patch)
tree6ce65c26b1b504d741b96498996edae55e0adcff /plugins/CuraEngineBackend/CuraEngineBackend.py
parent8f3827d5aef4c5a35c55bed8ec4ffc6eb7fb6c57 (diff)
Convert doxygen to rst for CuraEngineBackend
Diffstat (limited to 'plugins/CuraEngineBackend/CuraEngineBackend.py')
-rwxr-xr-xplugins/CuraEngineBackend/CuraEngineBackend.py256
1 files changed, 156 insertions, 100 deletions
diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py
index 3dd0589865..4de10c5ed0 100755
--- a/plugins/CuraEngineBackend/CuraEngineBackend.py
+++ b/plugins/CuraEngineBackend/CuraEngineBackend.py
@@ -42,12 +42,14 @@ catalog = i18nCatalog("cura")
class CuraEngineBackend(QObject, Backend):
backendError = Signal()
- ## 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.
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.
+ """
+
super().__init__()
# Find out where the engine is located, and how it is called.
# This depends on how Cura is packaged and which OS we are running on.
@@ -177,18 +179,22 @@ class CuraEngineBackend(QObject, Backend):
self._machine_error_checker = self._application.getMachineErrorChecker()
self._machine_error_checker.errorCheckFinished.connect(self._onStackErrorCheckFinished)
- ## Terminate the engine process.
- #
- # This function should terminate the engine process.
- # Called when closing the application.
def close(self) -> None:
+ """Terminate the engine process.
+
+ This function should terminate the engine process.
+ Called when closing the application.
+ """
+
# Terminate CuraEngine if it is still running at this point
self._terminate()
- ## 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.
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.
+ """
command = [self._application.getPreferences().getValue("backend/location"), "connect", "127.0.0.1:{0}".format(self._port), ""]
parser = argparse.ArgumentParser(prog = "cura", add_help = False)
@@ -199,17 +205,18 @@ class CuraEngineBackend(QObject, Backend):
return command
- ## Emitted when we get a message containing print duration and material amount.
- # This also implies the slicing has finished.
- # \param time The amount of time the print will take.
- # \param material_amount The amount of material the print will use.
printDurationMessage = Signal()
-
- ## Emitted when the slicing process starts.
+ """Emitted when we get a message containing print duration and material amount.
+
+ This also implies the slicing has finished.
+ :param time: The amount of time the print will take.
+ :param material_amount: The amount of material the print will use.
+ """
slicingStarted = Signal()
+ """Emitted when the slicing process starts."""
- ## Emitted when the slicing process is aborted forcefully.
slicingCancelled = Signal()
+ """Emitted when the slicing process is aborted forcefully."""
@pyqtSlot()
def stopSlicing(self) -> None:
@@ -226,14 +233,16 @@ class CuraEngineBackend(QObject, Backend):
if self._error_message:
self._error_message.hide()
- ## Manually triggers a reslice
@pyqtSlot()
def forceSlice(self) -> None:
+ """Manually triggers a reslice"""
+
self.markSliceAll()
self.slice()
- ## Perform a slice of the scene.
def slice(self) -> None:
+ """Perform a slice of the scene."""
+
Logger.log("i", "Starting to slice...")
self._slice_start_time = time()
if not self._build_plates_to_be_sliced:
@@ -289,9 +298,11 @@ class CuraEngineBackend(QObject, Backend):
self._start_slice_job.start()
self._start_slice_job.finished.connect(self._onStartSliceCompleted)
- ## Terminate the engine process.
- # Start the engine process by calling _createSocket()
def _terminate(self) -> None:
+ """Terminate the engine process.
+
+ Start the engine process by calling _createSocket()
+ """
self._slicing = False
self._stored_layer_data = []
if self._start_slice_job_build_plate in self._stored_optimized_layer_data:
@@ -316,15 +327,17 @@ class CuraEngineBackend(QObject, Backend):
except Exception as e: # terminating a process that is already terminating causes an exception, silently ignore this.
Logger.log("d", "Exception occurred while trying to kill the engine %s", str(e))
- ## 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.
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:
self._error_message.hide()
@@ -443,11 +456,13 @@ class CuraEngineBackend(QObject, Backend):
if self._slice_start_time:
Logger.log("d", "Sending slice message took %s seconds", time() - self._slice_start_time )
- ## 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)
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)
+ """
enable_timer = True
self._is_disabled = False
@@ -472,8 +487,9 @@ class CuraEngineBackend(QObject, Backend):
self.disableTimer()
return False
- ## Return a dict with number of objects per build plate
def _numObjectsPerBuildPlate(self) -> Dict[int, int]:
+ """Return a dict with number of objects per build plate"""
+
num_objects = defaultdict(int) #type: Dict[int, int]
for node in DepthFirstIterator(self._scene.getRoot()):
# Only count sliceable objects
@@ -483,12 +499,14 @@ class CuraEngineBackend(QObject, Backend):
num_objects[build_plate_number] += 1
return num_objects
- ## 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.
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"):
return
@@ -536,10 +554,12 @@ class CuraEngineBackend(QObject, Backend):
self._invokeSlice()
- ## Called when an error occurs in the socket connection towards the engine.
- #
- # \param error The exception that occurred.
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.
+ """
+
if self._application.isShuttingDown():
return
@@ -567,8 +587,9 @@ class CuraEngineBackend(QObject, Backend):
break
return has_slicable
- ## Remove old layer data (if any)
def _clearLayerData(self, build_plate_numbers: Set = None) -> None:
+ """Remove old layer data (if any)"""
+
# Clear out any old gcode
self._scene.gcode_dict = {} # type: ignore
@@ -583,8 +604,9 @@ class CuraEngineBackend(QObject, Backend):
if build_plate_number not in self._build_plates_to_be_sliced:
self._build_plates_to_be_sliced.append(build_plate_number)
- ## Convenient function: mark everything to slice, emit state and clear layer data
def needsSlicing(self) -> None:
+ """Convenient function: mark everything to slice, emit state and clear layer data"""
+
# CURA-6604: If there's no slicable object, do not (try to) trigger slice, which will clear all the current
# gcode. This can break Gcode file loading if it tries to remove it afterwards.
if not self.hasSlicableObject():
@@ -597,10 +619,12 @@ 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: 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.
+ """
if property == "value": # Only reslice if the value has changed.
self.needsSlicing()
self._onChanged()
@@ -618,25 +642,31 @@ class CuraEngineBackend(QObject, Backend):
self.needsSlicing()
self._onChanged()
- ## Called when a sliced layer data message is received from the engine.
- #
- # \param message The protobuf message containing sliced layer data.
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.
+ """
+
self._stored_layer_data.append(message)
- ## Called when an optimized sliced layer data message is received from the engine.
- #
- # \param message The protobuf message containing sliced layer data.
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.
+ """
+
if self._start_slice_job_build_plate is not None:
if self._start_slice_job_build_plate not in self._stored_optimized_layer_data:
self._stored_optimized_layer_data[self._start_slice_job_build_plate] = []
self._stored_optimized_layer_data[self._start_slice_job_build_plate].append(message)
- ## Called when a progress message is received from the engine.
- #
- # \param message The protobuf message containing the slicing progress.
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.
+ """
+
self.processingProgress.emit(message.amount)
self.setState(BackendState.Processing)
@@ -653,10 +683,12 @@ class CuraEngineBackend(QObject, Backend):
else:
self._change_timer.start()
- ## Called when the engine sends a message that slicing is finished.
- #
- # \param message The protobuf message signalling that slicing is finished.
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.
+ """
+
self.setState(BackendState.Done)
self.processingProgress.emit(1.0)
@@ -698,27 +730,32 @@ class CuraEngineBackend(QObject, Backend):
self.enableTimer() # manually enable timer to be able to invoke slice, also when in manual slice mode
self._invokeSlice()
- ## Called when a g-code message is received from the engine.
- #
- # \param message The protobuf message containing g-code, encoded as UTF-8.
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.
+ """
+
try:
self._scene.gcode_dict[self._start_slice_job_build_plate].append(message.data.decode("utf-8", "replace")) #type: ignore #Because we generate this attribute dynamically.
except KeyError: # Can occur if the g-code has been cleared while a slice message is still arriving from the other end.
pass # Throw the message away.
- ## 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.
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.
+ """
+
try:
self._scene.gcode_dict[self._start_slice_job_build_plate].insert(0, message.data.decode("utf-8", "replace")) #type: ignore #Because we generate this attribute dynamically.
except KeyError: # Can occur if the g-code has been cleared while a slice message is still arriving from the other end.
pass # Throw the message away.
- ## Creates a new socket connection.
def _createSocket(self, protocol_file: str = None) -> None:
+ """Creates a new socket connection."""
+
if not protocol_file:
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if not plugin_path:
@@ -728,10 +765,12 @@ class CuraEngineBackend(QObject, Backend):
super()._createSocket(protocol_file)
self._engine_is_fresh = True
- ## Called when anything has changed to the stuff that needs to be sliced.
- #
- # This indicates that we should probably re-slice soon.
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.
+ """
+
self.needsSlicing()
if self._use_timer:
# if the error check is scheduled, wait for the error check finish signal to trigger auto-slice,
@@ -745,11 +784,13 @@ class CuraEngineBackend(QObject, Backend):
else:
self._change_timer.start()
- ## 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
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
+ """
+
material_amounts = []
for index in range(message.repeatedMessageCount("materialEstimates")):
material_amounts.append(message.getRepeatedMessage("materialEstimates", index).material_amount)
@@ -757,10 +798,12 @@ class CuraEngineBackend(QObject, Backend):
times = self._parseMessagePrintTimes(message)
self.printDurationMessage.emit(self._start_slice_job_build_plate, times, material_amounts)
- ## Called for parsing message to retrieve estimated time per feature
- #
- # \param message The protobuf message containing the print time per feature
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
+ """
+
result = {
"inset_0": message.time_inset_0,
"inset_x": message.time_inset_x,
@@ -777,19 +820,22 @@ class CuraEngineBackend(QObject, Backend):
}
return result
- ## Called when the back-end connects to the front-end.
def _onBackendConnected(self) -> None:
+ """Called when the back-end connects to the front-end."""
+
if self._restart:
self._restart = False
self._onChanged()
- ## 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.
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.
+ """
+
self._tool_active = True # Do not react on scene change
self.disableTimer()
# Restart engine as soon as possible, we know we want to slice afterwards
@@ -797,12 +843,14 @@ class CuraEngineBackend(QObject, Backend):
self._terminate()
self._createSocket()
- ## 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.
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.
+ """
+
self._tool_active = False # React on scene change again
self.determineAutoSlicing() # Switch timer on if appropriate
# Process all the postponed scene changes
@@ -816,8 +864,9 @@ class CuraEngineBackend(QObject, Backend):
self._process_layers_job.finished.connect(self._onProcessLayersFinished)
self._process_layers_job.start()
- ## Called when the user changes the active view mode.
def _onActiveViewChanged(self) -> None:
+ """Called when the user changes the active view mode."""
+
view = self._application.getController().getActiveView()
if view:
active_build_plate = self._application.getMultiBuildPlateModel().activeBuildPlate
@@ -835,17 +884,20 @@ class CuraEngineBackend(QObject, Backend):
else:
self._layer_view_active = False
- ## Called when the back-end self-terminates.
- #
- # We should reset our state and start listening for new connections.
def _onBackendQuit(self) -> None:
+ """Called when the back-end self-terminates.
+
+ We should reset our state and start listening for new connections.
+ """
+
if not self._restart:
if self._process: # type: ignore
Logger.log("d", "Backend quit with return code %s. Resetting process and socket.", self._process.wait()) # type: ignore
self._process = None # type: ignore
- ## Called when the global container stack changes
def _onGlobalStackChanged(self) -> None:
+ """Called when the global container stack changes"""
+
if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onSettingChanged)
self._global_container_stack.containersChanged.disconnect(self._onChanged)
@@ -874,15 +926,18 @@ class CuraEngineBackend(QObject, Backend):
Logger.log("d", "See if there is more to slice(2)...")
self._invokeSlice()
- ## Connect slice function to timer.
def enableTimer(self) -> None:
+ """Connect slice function to timer."""
+
if not self._use_timer:
self._change_timer.timeout.connect(self.slice)
self._use_timer = True
- ## Disconnect slice function from timer.
- # This means that slicing will not be triggered automatically
def disableTimer(self) -> None:
+ """Disconnect slice function from timer.
+
+ This means that slicing will not be triggered automatically
+ """
if self._use_timer:
self._use_timer = False
self._change_timer.timeout.disconnect(self.slice)
@@ -894,8 +949,9 @@ class CuraEngineBackend(QObject, Backend):
if auto_slice:
self._change_timer.start()
- ## Tickle the backend so in case of auto slicing, it starts the timer.
def tickle(self) -> None:
+ """Tickle the backend so in case of auto slicing, it starts the timer."""
+
if self._use_timer:
self._change_timer.start()