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:
-rw-r--r--plugins/MonitorStage/MonitorStage.py144
-rw-r--r--plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py6
-rw-r--r--plugins/PerObjectSettingsTool/PerObjectSettingsTool.py27
-rw-r--r--plugins/PostProcessingPlugin/PostProcessingPlugin.py49
-rw-r--r--plugins/PostProcessingPlugin/Script.py61
-rw-r--r--plugins/PostProcessingPlugin/scripts/FilamentChange.py8
-rw-r--r--plugins/PostProcessingPlugin/scripts/PauseAtHeight.py11
-rw-r--r--plugins/PostProcessingPlugin/scripts/RetractContinue.py4
-rw-r--r--plugins/PostProcessingPlugin/scripts/SearchAndReplace.py11
9 files changed, 180 insertions, 141 deletions
diff --git a/plugins/MonitorStage/MonitorStage.py b/plugins/MonitorStage/MonitorStage.py
index 3d2a1c3f37..4e4c442b4c 100644
--- a/plugins/MonitorStage/MonitorStage.py
+++ b/plugins/MonitorStage/MonitorStage.py
@@ -1,72 +1,72 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-import os.path
-from UM.Application import Application
-from cura.Stages.CuraStage import CuraStage
-
-
-## Stage for monitoring a 3D printing while it's printing.
-class MonitorStage(CuraStage):
-
- def __init__(self, parent = None):
- super().__init__(parent)
-
- # Wait until QML engine is created, otherwise creating the new QML components will fail
- Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
- self._printer_output_device = None
-
- self._active_print_job = None
- self._active_printer = None
-
- def _setActivePrintJob(self, print_job):
- if self._active_print_job != print_job:
- self._active_print_job = print_job
-
- def _setActivePrinter(self, printer):
- if self._active_printer != printer:
- if self._active_printer:
- self._active_printer.activePrintJobChanged.disconnect(self._onActivePrintJobChanged)
- self._active_printer = printer
- if self._active_printer:
- self._setActivePrintJob(self._active_printer.activePrintJob)
- # Jobs might change, so we need to listen to it's changes.
- self._active_printer.activePrintJobChanged.connect(self._onActivePrintJobChanged)
- else:
- self._setActivePrintJob(None)
-
- def _onActivePrintJobChanged(self):
- self._setActivePrintJob(self._active_printer.activePrintJob)
-
- def _onActivePrinterChanged(self):
- self._setActivePrinter(self._printer_output_device.activePrinter)
-
- def _onOutputDevicesChanged(self):
- try:
- # We assume that you are monitoring the device with the highest priority.
- new_output_device = Application.getInstance().getMachineManager().printerOutputDevices[0]
- if new_output_device != self._printer_output_device:
- if self._printer_output_device:
- try:
- self._printer_output_device.printersChanged.disconnect(self._onActivePrinterChanged)
- except TypeError:
- # Ignore stupid "Not connected" errors.
- pass
-
- self._printer_output_device = new_output_device
-
- self._printer_output_device.printersChanged.connect(self._onActivePrinterChanged)
- self._setActivePrinter(self._printer_output_device.activePrinter)
- except IndexError:
- pass
-
- def _onEngineCreated(self):
- # We can only connect now, as we need to be sure that everything is loaded (plugins get created quite early)
- Application.getInstance().getMachineManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
- self._onOutputDevicesChanged()
-
- plugin_path = Application.getInstance().getPluginRegistry().getPluginPath(self.getPluginId())
- if plugin_path is not None:
- menu_component_path = os.path.join(plugin_path, "MonitorMenu.qml")
- main_component_path = os.path.join(plugin_path, "MonitorMain.qml")
- self.addDisplayComponent("menu", menu_component_path)
- self.addDisplayComponent("main", main_component_path)
+# Copyright (c) 2017 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+import os.path
+from UM.Application import Application
+from cura.Stages.CuraStage import CuraStage
+
+
+class MonitorStage(CuraStage):
+ """Stage for monitoring a 3D printing while it's printing."""
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ # Wait until QML engine is created, otherwise creating the new QML components will fail
+ Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
+ self._printer_output_device = None
+
+ self._active_print_job = None
+ self._active_printer = None
+
+ def _setActivePrintJob(self, print_job):
+ if self._active_print_job != print_job:
+ self._active_print_job = print_job
+
+ def _setActivePrinter(self, printer):
+ if self._active_printer != printer:
+ if self._active_printer:
+ self._active_printer.activePrintJobChanged.disconnect(self._onActivePrintJobChanged)
+ self._active_printer = printer
+ if self._active_printer:
+ self._setActivePrintJob(self._active_printer.activePrintJob)
+ # Jobs might change, so we need to listen to it's changes.
+ self._active_printer.activePrintJobChanged.connect(self._onActivePrintJobChanged)
+ else:
+ self._setActivePrintJob(None)
+
+ def _onActivePrintJobChanged(self):
+ self._setActivePrintJob(self._active_printer.activePrintJob)
+
+ def _onActivePrinterChanged(self):
+ self._setActivePrinter(self._printer_output_device.activePrinter)
+
+ def _onOutputDevicesChanged(self):
+ try:
+ # We assume that you are monitoring the device with the highest priority.
+ new_output_device = Application.getInstance().getMachineManager().printerOutputDevices[0]
+ if new_output_device != self._printer_output_device:
+ if self._printer_output_device:
+ try:
+ self._printer_output_device.printersChanged.disconnect(self._onActivePrinterChanged)
+ except TypeError:
+ # Ignore stupid "Not connected" errors.
+ pass
+
+ self._printer_output_device = new_output_device
+
+ self._printer_output_device.printersChanged.connect(self._onActivePrinterChanged)
+ self._setActivePrinter(self._printer_output_device.activePrinter)
+ except IndexError:
+ pass
+
+ def _onEngineCreated(self):
+ # We can only connect now, as we need to be sure that everything is loaded (plugins get created quite early)
+ Application.getInstance().getMachineManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
+ self._onOutputDevicesChanged()
+
+ plugin_path = Application.getInstance().getPluginRegistry().getPluginPath(self.getPluginId())
+ if plugin_path is not None:
+ menu_component_path = os.path.join(plugin_path, "MonitorMenu.qml")
+ main_component_path = os.path.join(plugin_path, "MonitorMain.qml")
+ self.addDisplayComponent("menu", menu_component_path)
+ self.addDisplayComponent("main", main_component_path)
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
index 78da0512f7..c44e4a4df3 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
@@ -15,9 +15,11 @@ from cura.Settings.ExtruderManager import ExtruderManager #To get global-inherit
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
-## The per object setting visibility handler ensures that only setting
-# definitions that have a matching instance Container are returned as visible.
class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHandler.SettingVisibilityHandler):
+ """The per object setting visibility handler ensures that only setting
+
+ definitions that have a matching instance Container are returned as visible.
+ """
def __init__(self, parent = None, *args, **kwargs):
super().__init__(parent = parent, *args, **kwargs)
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py
index 4f0d90a8e3..d23096c0a3 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py
@@ -12,9 +12,11 @@ from UM.Settings.SettingInstance import SettingInstance
from UM.Event import Event
-## This tool allows the user to add & change settings per node in the scene.
-# The settings per object are kept in a ContainerStack, which is linked to a node by decorator.
class PerObjectSettingsTool(Tool):
+ """This tool allows the user to add & change settings per node in the scene.
+
+ The settings per object are kept in a ContainerStack, which is linked to a node by decorator.
+ """
def __init__(self):
super().__init__()
self._model = None
@@ -48,26 +50,31 @@ class PerObjectSettingsTool(Tool):
except AttributeError:
return ""
- ## Gets the active extruder of the currently selected object.
- #
- # \return The active extruder of the currently selected object.
def getSelectedActiveExtruder(self):
+ """Gets the active extruder of the currently selected object.
+
+ :return: The active extruder of the currently selected object.
+ """
+
selected_object = Selection.getSelectedObject(0)
return selected_object.callDecoration("getActiveExtruder")
- ## Changes the active extruder of the currently selected object.
- #
- # \param extruder_stack_id The ID of the extruder to print the currently
- # selected object with.
def setSelectedActiveExtruder(self, extruder_stack_id):
+ """Changes the active extruder of the currently selected object.
+
+ :param extruder_stack_id: The ID of the extruder to print the currently
+ selected object with.
+ """
+
selected_object = Selection.getSelectedObject(0)
stack = selected_object.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway.
if not stack:
selected_object.addDecorator(SettingOverrideDecorator())
selected_object.callDecoration("setActiveExtruder", extruder_stack_id)
- ## Returns True when the mesh_type was changed, False when current mesh_type == mesh_type
def setMeshType(self, mesh_type: str) -> bool:
+ """Returns True when the mesh_type was changed, False when current mesh_type == mesh_type"""
+
old_mesh_type = self.getMeshType()
if old_mesh_type == mesh_type:
return False
diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
index 9bf8062ffd..c1135640dd 100644
--- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py
+++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
@@ -27,9 +27,8 @@ if TYPE_CHECKING:
from .Script import Script
-## The post processing plugin is an Extension type plugin that enables pre-written scripts to post process generated
-# g-code files.
class PostProcessingPlugin(QObject, Extension):
+ """Extension type plugin that enables pre-written scripts to post process g-code files."""
def __init__(self, parent = None) -> None:
QObject.__init__(self, parent)
Extension.__init__(self)
@@ -69,8 +68,9 @@ class PostProcessingPlugin(QObject, Extension):
except IndexError:
return ""
- ## Execute all post-processing scripts on the gcode.
def execute(self, output_device) -> None:
+ """Execute all post-processing scripts on the gcode."""
+
scene = Application.getInstance().getController().getScene()
# If the scene does not have a gcode, do nothing
if not hasattr(scene, "gcode_dict"):
@@ -119,9 +119,10 @@ class PostProcessingPlugin(QObject, Extension):
self.selectedIndexChanged.emit() #Ensure that settings are updated
self._propertyChanged()
- ## Remove a script from the active script list by index.
@pyqtSlot(int)
def removeScriptByIndex(self, index: int) -> None:
+ """Remove a script from the active script list by index."""
+
self._script_list.pop(index)
if len(self._script_list) - 1 < self._selected_script_index:
self._selected_script_index = len(self._script_list) - 1
@@ -129,10 +130,12 @@ class PostProcessingPlugin(QObject, Extension):
self.selectedIndexChanged.emit() # Ensure that settings are updated
self._propertyChanged()
- ## Load all scripts from all paths where scripts can be found.
- #
- # This should probably only be done on init.
def loadAllScripts(self) -> None:
+ """Load all scripts from all paths where scripts can be found.
+
+ This should probably only be done on init.
+ """
+
if self._loaded_scripts: # Already loaded.
return
@@ -152,10 +155,12 @@ class PostProcessingPlugin(QObject, Extension):
self.loadScripts(path)
- ## Load all scripts from provided path.
- # This should probably only be done on init.
- # \param path Path to check for scripts.
def loadScripts(self, path: str) -> None:
+ """Load all scripts from provided path.
+
+ This should probably only be done on init.
+ :param path: Path to check for scripts.
+ """
if ApplicationMetadata.IsEnterpriseVersion:
# Delete all __pycache__ not in installation folder, as it may present a security risk.
@@ -173,8 +178,8 @@ class PostProcessingPlugin(QObject, Extension):
if not is_in_installation_path:
TrustBasics.removeCached(path)
- ## Load all scripts in the scripts folders
scripts = pkgutil.iter_modules(path = [path])
+ """Load all scripts in the scripts folders"""
for loader, script_name, ispkg in scripts:
# Iterate over all scripts.
if script_name not in sys.modules:
@@ -278,9 +283,8 @@ class PostProcessingPlugin(QObject, Extension):
self.scriptListChanged.emit()
self._propertyChanged()
- ## When the global container stack is changed, swap out the list of active
- # scripts.
def _onGlobalContainerStackChanged(self) -> None:
+ """When the global container stack is changed, swap out the list of active scripts."""
if self._global_container_stack:
self._global_container_stack.metaDataChanged.disconnect(self._restoreScriptInforFromMetadata)
@@ -323,8 +327,12 @@ class PostProcessingPlugin(QObject, Extension):
# We do want to listen to other events.
self._global_container_stack.metaDataChanged.connect(self._restoreScriptInforFromMetadata)
- ## Creates the view used by show popup. The view is saved because of the fairly aggressive garbage collection.
def _createView(self) -> None:
+ """Creates the view used by show popup.
+
+ The view is saved because of the fairly aggressive garbage collection.
+ """
+
Logger.log("d", "Creating post processing plugin view.")
self.loadAllScripts()
@@ -340,8 +348,9 @@ class PostProcessingPlugin(QObject, Extension):
# Create the save button component
CuraApplication.getInstance().addAdditionalComponent("saveButton", self._view.findChild(QObject, "postProcessingSaveAreaButton"))
- ## Show the (GUI) popup of the post processing plugin.
def showPopup(self) -> None:
+ """Show the (GUI) popup of the post processing plugin."""
+
if self._view is None:
self._createView()
if self._view is None:
@@ -349,11 +358,13 @@ class PostProcessingPlugin(QObject, Extension):
return
self._view.show()
- ## Property changed: trigger re-slice
- # To do this we use the global container stack propertyChanged.
- # Re-slicing is necessary for setting changes in this plugin, because the changes
- # are applied only once per "fresh" gcode
def _propertyChanged(self) -> None:
+ """Property changed: trigger re-slice
+
+ To do this we use the global container stack propertyChanged.
+ Re-slicing is necessary for setting changes in this plugin, because the changes
+ are applied only once per "fresh" gcode
+ """
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack is not None:
global_container_stack.propertyChanged.emit("post_processing_plugin", "value")
diff --git a/plugins/PostProcessingPlugin/Script.py b/plugins/PostProcessingPlugin/Script.py
index e502f107f9..d15b209478 100644
--- a/plugins/PostProcessingPlugin/Script.py
+++ b/plugins/PostProcessingPlugin/Script.py
@@ -23,9 +23,10 @@ if TYPE_CHECKING:
from UM.Settings.Interfaces import DefinitionContainerInterface
-## Base class for scripts. All scripts should inherit the script class.
@signalemitter
class Script:
+ """Base class for scripts. All scripts should inherit the script class."""
+
def __init__(self) -> None:
super().__init__()
self._stack = None # type: Optional[ContainerStack]
@@ -78,13 +79,15 @@ class Script:
if global_container_stack is not None:
global_container_stack.propertyChanged.emit(key, property_name)
- ## Needs to return a dict that can be used to construct a settingcategory file.
- # See the example script for an example.
- # It follows the same style / guides as the Uranium settings.
- # Scripts can either override getSettingData directly, or use getSettingDataString
- # to return a string that will be parsed as json. The latter has the benefit over
- # returning a dict in that the order of settings is maintained.
def getSettingData(self) -> Dict[str, Any]:
+ """Needs to return a dict that can be used to construct a settingcategory file.
+
+ See the example script for an example.
+ It follows the same style / guides as the Uranium settings.
+ Scripts can either override getSettingData directly, or use getSettingDataString
+ to return a string that will be parsed as json. The latter has the benefit over
+ returning a dict in that the order of settings is maintained.
+ """
setting_data_as_string = self.getSettingDataString()
setting_data = json.loads(setting_data_as_string, object_pairs_hook = collections.OrderedDict)
return setting_data
@@ -104,15 +107,18 @@ class Script:
return self._stack.getId()
return None
- ## Convenience function that retrieves value of a setting from the stack.
def getSettingValueByKey(self, key: str) -> Any:
+ """Convenience function that retrieves value of a setting from the stack."""
+
if self._stack is not None:
return self._stack.getProperty(key, "value")
return None
- ## Convenience function that finds the value in a line of g-code.
- # When requesting key = x from line "G1 X100" the value 100 is returned.
def getValue(self, line: str, key: str, default = None) -> Any:
+ """Convenience function that finds the value in a line of g-code.
+
+ When requesting key = x from line "G1 X100" the value 100 is returned.
+ """
if not key in line or (';' in line and line.find(key) > line.find(';')):
return default
sub_part = line[line.find(key) + 1:]
@@ -127,20 +133,23 @@ class Script:
except ValueError: #Not a number at all.
return default
- ## Convenience function to produce a line of g-code.
- #
- # You can put in an original g-code line and it'll re-use all the values
- # in that line.
- # All other keyword parameters are put in the result in g-code's format.
- # For instance, if you put ``G=1`` in the parameters, it will output
- # ``G1``. If you put ``G=1, X=100`` in the parameters, it will output
- # ``G1 X100``. The parameters G and M will always be put first. The
- # parameters T and S will be put second (or first if there is no G or M).
- # The rest of the parameters will be put in arbitrary order.
- # \param line The original g-code line that must be modified. If not
- # provided, an entirely new g-code line will be produced.
- # \return A line of g-code with the desired parameters filled in.
def putValue(self, line: str = "", **kwargs) -> str:
+ """Convenience function to produce a line of g-code.
+
+ You can put in an original g-code line and it'll re-use all the values
+ in that line.
+ All other keyword parameters are put in the result in g-code's format.
+ For instance, if you put ``G=1`` in the parameters, it will output
+ ``G1``. If you put ``G=1, X=100`` in the parameters, it will output
+ ``G1 X100``. The parameters G and M will always be put first. The
+ parameters T and S will be put second (or first if there is no G or M).
+ The rest of the parameters will be put in arbitrary order.
+
+ :param line: The original g-code line that must be modified. If not
+ provided, an entirely new g-code line will be produced.
+ :return: A line of g-code with the desired parameters filled in.
+ """
+
#Strip the comment.
comment = ""
if ";" in line:
@@ -179,7 +188,9 @@ class Script:
return result
- ## This is called when the script is executed.
- # It gets a list of g-code strings and needs to return a (modified) list.
def execute(self, data: List[str]) -> List[str]:
+ """This is called when the script is executed.
+
+ It gets a list of g-code strings and needs to return a (modified) list.
+ """
raise NotImplementedError()
diff --git a/plugins/PostProcessingPlugin/scripts/FilamentChange.py b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
index 943ca30f2e..351b985d49 100644
--- a/plugins/PostProcessingPlugin/scripts/FilamentChange.py
+++ b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
@@ -63,10 +63,12 @@ class FilamentChange(Script):
}
}"""
- ## Inserts the filament change g-code at specific layer numbers.
- # \param data A list of layers of g-code.
- # \return A similar list, with filament change commands inserted.
def execute(self, data: List[str]):
+ """Inserts the filament change g-code at specific layer numbers.
+
+ :param data: A list of layers of g-code.
+ :return: A similar list, with filament change commands inserted.
+ """
layer_nums = self.getSettingValueByKey("layer_number")
initial_retract = self.getSettingValueByKey("initial_retract")
later_retract = self.getSettingValueByKey("later_retract")
diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
index 1ba8b8213b..766677af2a 100644
--- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
+++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
@@ -134,9 +134,8 @@ class PauseAtHeight(Script):
}
}"""
- ## Get the X and Y values for a layer (will be used to get X and Y of the
- # layer after the pause).
def getNextXY(self, layer: str) -> Tuple[float, float]:
+ """Get the X and Y values for a layer (will be used to get X and Y of the layer after the pause)."""
lines = layer.split("\n")
for line in lines:
if self.getValue(line, "X") is not None and self.getValue(line, "Y") is not None:
@@ -145,10 +144,12 @@ class PauseAtHeight(Script):
return x, y
return 0, 0
- ## Inserts the pause commands.
- # \param data: List of layers.
- # \return New list of layers.
def execute(self, data: List[str]) -> List[str]:
+ """Inserts the pause commands.
+
+ :param data: List of layers.
+ :return: New list of layers.
+ """
pause_at = self.getSettingValueByKey("pause_at")
pause_height = self.getSettingValueByKey("pause_height")
pause_layer = self.getSettingValueByKey("pause_layer")
diff --git a/plugins/PostProcessingPlugin/scripts/RetractContinue.py b/plugins/PostProcessingPlugin/scripts/RetractContinue.py
index e437439287..3e095bd395 100644
--- a/plugins/PostProcessingPlugin/scripts/RetractContinue.py
+++ b/plugins/PostProcessingPlugin/scripts/RetractContinue.py
@@ -5,8 +5,10 @@ import math
from ..Script import Script
-## Continues retracting during all travel moves.
+
class RetractContinue(Script):
+ """Continues retracting during all travel moves."""
+
def getSettingDataString(self):
return """{
"name": "Retract Continue",
diff --git a/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py b/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py
index 68d697e470..b601a037da 100644
--- a/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py
+++ b/plugins/PostProcessingPlugin/scripts/SearchAndReplace.py
@@ -5,11 +5,14 @@ import re #To perform the search and replace.
from ..Script import Script
-## Performs a search-and-replace on all g-code.
-#
-# Due to technical limitations, the search can't cross the border between
-# layers.
+
class SearchAndReplace(Script):
+ """Performs a search-and-replace on all g-code.
+
+ Due to technical limitations, the search can't cross the border between
+ layers.
+ """
+
def getSettingDataString(self):
return """{
"name": "Search and Replace",