Remove trailing whitespace from Python files

This commit is contained in:
Nino van Hooff 2020-05-29 14:30:33 +02:00
parent 1e33360c35
commit 89f0970a88
157 changed files with 562 additions and 562 deletions

View file

@ -13,7 +13,7 @@ import sys
def find_json_files(work_dir: str) -> list:
"""Finds all JSON files in the given directory recursively and returns a list of those files in absolute paths.
:param work_dir: The directory to look for JSON files recursively.
:return: A list of JSON files in absolute paths that are found in the given directory.
"""
@ -28,7 +28,7 @@ def find_json_files(work_dir: str) -> list:
def remove_entries_from_json_file(file_path: str, entries: list) -> None:
"""Removes the given entries from the given JSON file. The file will modified in-place.
:param file_path: The JSON file to modify.
:param entries: A list of strings as entries to remove.
:return: None

View file

@ -10,9 +10,9 @@ if TYPE_CHECKING:
class Backups:
"""The back-ups API provides a version-proof bridge between Cura's
BackupManager and plug-ins that hook into it.
Usage:
.. code-block:: python
@ -28,7 +28,7 @@ class Backups:
def createBackup(self) -> Tuple[Optional[bytes], Optional[Dict[str, Any]]]:
"""Create a new back-up using the BackupsManager.
:return: Tuple containing a ZIP file with the back-up data and a dict with metadata about the back-up.
"""
@ -36,7 +36,7 @@ class Backups:
def restoreBackup(self, zip_file: bytes, meta_data: Dict[str, Any]) -> None:
"""Restore a back-up using the BackupsManager.
:param zip_file: A ZIP file containing the actual back-up data.
:param meta_data: Some metadata needed for restoring a back-up, like the Cura version number.
"""

View file

@ -10,9 +10,9 @@ if TYPE_CHECKING:
class Settings:
"""The Interface.Settings API provides a version-proof bridge
between Cura's
(currently) sidebar UI and plug-ins that hook into it.
Usage:
.. code-block:: python
@ -34,7 +34,7 @@ class Settings:
def addContextMenuItem(self, menu_item: dict) -> None:
"""Add items to the sidebar context menu.
:param menu_item: dict containing the menu item to add.
"""
@ -42,7 +42,7 @@ class Settings:
def getContextMenuItems(self) -> list:
"""Get all custom items currently added to the sidebar context menu.
:return: List containing all custom context menu items.
"""

View file

@ -11,9 +11,9 @@ if TYPE_CHECKING:
class Interface:
"""The Interface class serves as a common root for the specific API
methods for each interface element.
Usage:
.. code-block:: python

View file

@ -23,7 +23,7 @@ class ShapeArray:
@classmethod
def fromPolygon(cls, vertices: numpy.array, scale: float = 1) -> "ShapeArray":
"""Instantiate from a bunch of vertices
:param vertices:
:param scale: scale the coordinates
:return: a shape array instantiated from a bunch of vertices
@ -52,7 +52,7 @@ class ShapeArray:
@classmethod
def fromNode(cls, node: "SceneNode", min_offset: float, scale: float = 0.5, include_children: bool = False) -> Tuple[Optional["ShapeArray"], Optional["ShapeArray"]]:
"""Instantiate an offset and hull ShapeArray from a scene node.
:param node: source node where the convex hull must be present
:param min_offset: offset for the offset ShapeArray
:param scale: scale the coordinates
@ -100,7 +100,7 @@ class ShapeArray:
@classmethod
def arrayFromPolygon(cls, shape: Tuple[int, int], vertices: numpy.array) -> numpy.array:
"""Create :py:class:`numpy.ndarray` with dimensions defined by shape
Fills polygon defined by vertices with ones, all other values zero
Only works correctly for convex hull vertices
Originally from: `Stackoverflow - generating a filled polygon inside a numpy array <https://stackoverflow.com/questions/37117878/generating-a-filled-polygon-inside-a-numpy-array>`_
@ -128,7 +128,7 @@ class ShapeArray:
@classmethod
def _check(cls, p1: numpy.array, p2: numpy.array, base_array: numpy.array) -> Optional[numpy.array]:
"""Return indices that mark one side of the line, used by arrayFromPolygon
Uses the line defined by p1 and p2 to check array of
input indices against interpolated value
Returns boolean array, with True inside and False outside of shape

View file

@ -20,7 +20,7 @@ if TYPE_CHECKING:
class Backup:
"""The back-up class holds all data about a back-up.
It is also responsible for reading and writing the zip file to the user data folder.
"""
@ -68,7 +68,7 @@ class Backup:
material_count = len([s for s in files if "materials/" in s]) - 1
profile_count = len([s for s in files if "quality_changes/" in s]) - 1
plugin_count = len([s for s in files if "plugin.json" in s])
# Store the archive and metadata so the BackupManager can fetch them when needed.
self.zip_file = buffer.getvalue()
self.meta_data = {
@ -81,7 +81,7 @@ class Backup:
def _makeArchive(self, buffer: "io.BytesIO", root_path: str) -> Optional[ZipFile]:
"""Make a full archive from the given root path with the given name.
:param root_path: The root directory to archive recursively.
:return: The archive as bytes.
"""
@ -111,7 +111,7 @@ class Backup:
def restore(self) -> bool:
"""Restore this back-up.
:return: Whether we had success or not.
"""
@ -151,7 +151,7 @@ class Backup:
@staticmethod
def _extractArchive(archive: "ZipFile", target_path: str) -> bool:
"""Extract the whole archive to the given target path.
:param archive: The archive as ZipFile.
:param target_path: The target path.
:return: Whether we had success or not.

View file

@ -166,7 +166,7 @@ class BuildVolume(SceneNode):
def _updateNodeListeners(self, node: SceneNode):
"""Updates the listeners that listen for changes in per-mesh stacks.
:param node: The node for which the decorators changed.
"""
@ -587,7 +587,7 @@ class BuildVolume(SceneNode):
def _calculateExtraZClearance(self, extruders: List["ContainerStack"]) -> float:
if not self._global_container_stack:
return 0
extra_z = 0.0
for extruder in extruders:
if extruder.getProperty("retraction_hop_enabled", "value"):
@ -728,7 +728,7 @@ class BuildVolume(SceneNode):
def _updateDisallowedAreasAndRebuild(self):
"""Calls :py:meth:`cura.BuildVolume._updateDisallowedAreas` and makes sure the changes appear in the scene.
This is required for a signal to trigger the update in one go. The
:py:meth:`cura.BuildVolume._updateDisallowedAreas` method itself shouldn't call
:py:meth:`cura.BuildVolume.rebuild`, since there may be other changes before it needs to be rebuilt,
@ -798,9 +798,9 @@ class BuildVolume(SceneNode):
def _computeDisallowedAreasPrinted(self, used_extruders):
"""Computes the disallowed areas for objects that are printed with print features.
This means that the brim, travel avoidance and such will be applied to these features.
:return: A dictionary with for each used extruder ID the disallowed areas where that extruder may not print.
"""
@ -843,10 +843,10 @@ class BuildVolume(SceneNode):
def _computeDisallowedAreasPrimeBlob(self, border_size: float, used_extruders: List["ExtruderStack"]) -> Dict[str, List[Polygon]]:
"""Computes the disallowed areas for the prime blobs.
These are special because they are not subject to things like brim or travel avoidance. They do get a dilute
with the border size though because they may not intersect with brims and such of other objects.
:param border_size: The size with which to offset the disallowed areas due to skirt, brim, travel avoid distance
, etc.
:param used_extruders: The extruder stacks to generate disallowed areas for.
@ -882,7 +882,7 @@ class BuildVolume(SceneNode):
def _computeDisallowedAreasStatic(self, border_size:float, used_extruders: List["ExtruderStack"]) -> Dict[str, List[Polygon]]:
"""Computes the disallowed areas that are statically placed in the machine.
It computes different disallowed areas depending on the offset of the extruder. The resulting dictionary will
therefore have an entry for each extruder that is used.
@ -1024,9 +1024,9 @@ class BuildVolume(SceneNode):
def _getSettingFromAllExtruders(self, setting_key: str) -> List[Any]:
"""Private convenience function to get a setting from every extruder.
For single extrusion machines, this gets the setting from the global stack.
:return: A sequence of setting values, one for each extruder.
"""
@ -1116,7 +1116,7 @@ class BuildVolume(SceneNode):
def getEdgeDisallowedSize(self):
"""Calculate the disallowed radius around the edge.
This disallowed radius is to allow for space around the models that is not part of the collision radius,
such as bed adhesion (skirt/brim/raft) and travel avoid distance.
"""

View file

@ -237,7 +237,7 @@ class CrashHandler:
scope.set_tag("locale_os", self.data["locale_os"])
scope.set_tag("locale_cura", self.cura_locale)
scope.set_tag("is_enterprise", ApplicationMetadata.IsEnterpriseVersion)
scope.set_user({"id": str(uuid.getnode())})
return group

View file

@ -78,7 +78,7 @@ class CuraActions(QObject):
@pyqtSlot(int)
def multiplySelection(self, count: int) -> None:
"""Multiply all objects in the selection
:param count: The number of times to multiply the selection.
"""
@ -114,7 +114,7 @@ class CuraActions(QObject):
@pyqtSlot(str)
def setExtruderForSelection(self, extruder_id: str) -> None:
"""Set the extruder that should be used to print the selection.
:param extruder_id: The ID of the extruder stack to use for the selected objects.
"""

View file

@ -730,7 +730,7 @@ class CuraApplication(QtApplication):
def _loadPlugins(self) -> None:
"""Handle loading of all plugin types (and the backend explicitly)
:py:class:`Uranium.UM.PluginRegistry`
"""
@ -759,7 +759,7 @@ class CuraApplication(QtApplication):
def _setLoadingHint(self, hint: str):
"""Set a short, user-friendly hint about current loading status.
The way this message is displayed depends on application state
"""
@ -1010,7 +1010,7 @@ class CuraApplication(QtApplication):
def getMachineActionManager(self, *args: Any) -> MachineActionManager.MachineActionManager:
"""Get the machine action manager
We ignore any *args given to this, as we also register the machine manager as qml singleton.
It wants to give this function an engine and script engine, but we don't care about that.
"""
@ -1068,7 +1068,7 @@ class CuraApplication(QtApplication):
def registerObjects(self, engine):
"""Registers objects for the QML engine to use.
:param engine: The QML engine.
"""
@ -1391,7 +1391,7 @@ class CuraApplication(QtApplication):
def arrange(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode]) -> None:
"""Arrange a set of nodes given a set of fixed nodes
:param nodes: nodes that we have to place
:param fixed_nodes: nodes that are placed in the arranger before finding spots for nodes
"""
@ -1685,7 +1685,7 @@ class CuraApplication(QtApplication):
@pyqtSlot(str, "QVariant")
def addAdditionalComponent(self, area_id: str, component):
"""Add a component to a list of components to be reparented to another area in the GUI.
The actual reparenting is done by the area itself.
:param area_id: dentifying name of the area to which the component should be reparented
:param (QQuickComponent) component: The component that should be reparented
@ -1707,7 +1707,7 @@ class CuraApplication(QtApplication):
@pyqtSlot(QUrl)
def readLocalFile(self, file: QUrl, project_mode: Optional[str] = None):
"""Open a local file
:param project_mode: How to handle project files. Either None(default): Follow user preference, "open_as_model"
or "open_as_project". This parameter is only considered if the file is a project file.
"""

View file

@ -76,7 +76,7 @@ class Layer:
def createMeshOrJumps(self, make_mesh: bool) -> MeshData:
builder = MeshBuilder()
line_count = 0
if make_mesh:
for polygon in self._polygons:
@ -87,7 +87,7 @@ class Layer:
# Reserve the necessary space for the data upfront
builder.reserveFaceAndVertexCount(2 * line_count, 4 * line_count)
for polygon in self._polygons:
# Filter out the types of lines we are not interested in depending on whether we are drawing the mesh or the jumps.
index_mask = numpy.logical_not(polygon.jumpMask) if make_mesh else polygon.jumpMask
@ -96,7 +96,7 @@ class Layer:
points = numpy.concatenate((polygon.data[:-1], polygon.data[1:]), 1)[index_mask.ravel()]
# Line types of the points we want to draw
line_types = polygon.types[index_mask]
# Shift the z-axis according to previous implementation.
if make_mesh:
points[polygon.isInfillOrSkinType(line_types), 1::3] -= 0.01
@ -118,5 +118,5 @@ class Layer:
f_colors = numpy.repeat(polygon.mapLineTypeToColor(line_types), 4, 0)
builder.addFacesWithColor(f_points, f_indices, f_colors)
return builder.build()

View file

@ -5,7 +5,7 @@ from UM.Mesh.MeshData import MeshData
class LayerData(MeshData):
"""Class to holds the layer mesh and information about the layers.
Immutable, use :py:class:`cura.LayerDataBuilder.LayerDataBuilder` to create one of these.
"""

View file

@ -45,7 +45,7 @@ class LayerDataBuilder(MeshBuilder):
def build(self, material_color_map, line_type_brightness = 1.0):
"""Return the layer data as :py:class:`cura.LayerData.LayerData`.
:param material_color_map: [r, g, b, a] for each extruder row.
:param line_type_brightness: compatibility layer view uses line type brightness of 0.5
"""

View file

@ -62,21 +62,21 @@ class LayerPolygon:
# re-used and can save alot of memory usage.
self._color_map = LayerPolygon.getColorMap()
self._colors = self._color_map[self._types] # type: numpy.ndarray
# When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType
# Should be generated in better way, not hardcoded.
self._is_infill_or_skin_type_map = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0], dtype = numpy.bool)
self._build_cache_line_mesh_mask = None # type: Optional[numpy.ndarray]
self._build_cache_needed_points = None # type: Optional[numpy.ndarray]
def buildCache(self) -> None:
# For the line mesh we do not draw Infill or Jumps. Therefore those lines are filtered out.
self._build_cache_line_mesh_mask = numpy.ones(self._jump_mask.shape, dtype = bool)
mesh_line_count = numpy.sum(self._build_cache_line_mesh_mask)
self._index_begin = 0
self._index_end = mesh_line_count
self._build_cache_needed_points = numpy.ones((len(self._types), 2), dtype = numpy.bool)
# Only if the type of line segment changes do we need to add an extra vertex to change colors
self._build_cache_needed_points[1:, 0][:, numpy.newaxis] = self._types[1:] != self._types[:-1]
@ -88,9 +88,9 @@ class LayerPolygon:
def build(self, vertex_offset: int, index_offset: int, vertices: numpy.ndarray, colors: numpy.ndarray, line_dimensions: numpy.ndarray, feedrates: numpy.ndarray, extruders: numpy.ndarray, line_types: numpy.ndarray, indices: numpy.ndarray) -> None:
"""Set all the arrays provided by the function caller, representing the LayerPolygon
The arrays are either by vertex or by indices.
:param vertex_offset: determines where to start and end filling the arrays
:param index_offset: determines where to start and end filling the arrays
:param vertices: vertex numpy array to be filled
@ -111,16 +111,16 @@ class LayerPolygon:
line_mesh_mask = self._build_cache_line_mesh_mask
needed_points_list = self._build_cache_needed_points
# Index to the points we need to represent the line mesh. This is constructed by generating simple
# start and end points for each line. For line segment n these are points n and n+1. Row n reads [n n+1]
# Then then the indices for the points we don't need are thrown away based on the pre-calculated list.
index_list = ( numpy.arange(len(self._types)).reshape((-1, 1)) + numpy.array([[0, 1]]) ).reshape((-1, 1))[needed_points_list.reshape((-1, 1))]
# The relative values of begin and end indices have already been set in buildCache, so we only need to offset them to the parents offset.
self._vertex_begin += vertex_offset
self._vertex_end += vertex_offset
# Points are picked based on the index list to get the vertices needed.
vertices[self._vertex_begin:self._vertex_end, :] = self._data[index_list, :]
@ -142,14 +142,14 @@ class LayerPolygon:
# The relative values of begin and end indices have already been set in buildCache, so we only need to offset them to the parents offset.
self._index_begin += index_offset
self._index_end += index_offset
indices[self._index_begin:self._index_end, :] = numpy.arange(self._index_end-self._index_begin, dtype = numpy.int32).reshape((-1, 1))
# When the line type changes the index needs to be increased by 2.
indices[self._index_begin:self._index_end, :] += numpy.cumsum(needed_points_list[line_mesh_mask.ravel(), 0], dtype = numpy.int32).reshape((-1, 1))
# Each line segment goes from it's starting point p to p+1, offset by the vertex index.
# The -1 is to compensate for the neccecarily True value of needed_points_list[0,0] which causes an unwanted +1 in cumsum above.
indices[self._index_begin:self._index_end, :] += numpy.array([self._vertex_begin - 1, self._vertex_begin])
self._build_cache_line_mesh_mask = None
self._build_cache_needed_points = None
@ -195,7 +195,7 @@ class LayerPolygon:
@property
def lineFeedrates(self):
return self._line_feedrates
@property
def jumpMask(self):
return self._jump_mask

View file

@ -62,7 +62,7 @@ class MachineAction(QObject, PluginObject):
@pyqtSlot()
def reset(self) -> None:
"""Reset the action to it's default state.
This should not be re-implemented by child classes, instead re-implement _reset.
:py:meth:`cura.MachineAction.MachineAction._reset`
@ -73,7 +73,7 @@ class MachineAction(QObject, PluginObject):
def _reset(self) -> None:
"""Protected implementation of reset.
See also :py:meth:`cura.MachineAction.MachineAction.reset`
"""

View file

@ -11,14 +11,14 @@ from UM.Settings.InstanceContainer import InstanceContainer
class ContainerNode:
"""A node in the container tree. It represents one container.
The container it represents is referenced by its container_id. During normal use of the tree, this container is
not constructed. Only when parts of the tree need to get loaded in the container stack should it get constructed.
"""
def __init__(self, container_id: str) -> None:
"""Creates a new node for the container tree.
:param container_id: The ID of the container that this node should represent.
"""
@ -28,7 +28,7 @@ class ContainerNode:
def getMetadata(self) -> Dict[str, Any]:
"""Gets the metadata of the container that this node represents.
Getting the metadata from the container directly is about 10x as fast.
:return: The metadata of the container in this node.
@ -38,7 +38,7 @@ class ContainerNode:
def getMetaDataEntry(self, entry: str, default: Any = None) -> Any:
"""Get an entry from the metadata of the container that this node contains.
This is just a convenience function.
:param entry: The metadata entry key to return.
@ -56,7 +56,7 @@ class ContainerNode:
@property
def container(self) -> Optional[InstanceContainer]:
"""The container that this node's container ID refers to.
This can be used to finally instantiate the container in order to put it in the container stack.
:return: A container.

View file

@ -21,9 +21,9 @@ if TYPE_CHECKING:
class ContainerTree:
"""This class contains a look-up tree for which containers are available at which stages of configuration.
The tree starts at the machine definitions. For every distinct definition there will be one machine node here.
All of the fallbacks for material choices, quality choices, etc. should be encoded in this tree. There must
always be at least one child node (for nodes that have children) but that child node may be a node representing
the empty instance container.
@ -44,7 +44,7 @@ class ContainerTree:
def getCurrentQualityGroups(self) -> Dict[str, "QualityGroup"]:
"""Get the quality groups available for the currently activated printer.
This contains all quality groups, enabled or disabled. To check whether the quality group can be activated,
test for the ``QualityGroup.is_available`` property.
@ -61,7 +61,7 @@ class ContainerTree:
def getCurrentQualityChangesGroups(self) -> List["QualityChangesGroup"]:
"""Get the quality changes groups available for the currently activated printer.
This contains all quality changes groups, enabled or disabled. To check whether the quality changes group can
be activated, test for the ``QualityChangesGroup.is_available`` property.
@ -84,7 +84,7 @@ class ContainerTree:
class _MachineNodeMap:
"""Dictionary-like object that contains the machines.
This handles the lazy loading of MachineNodes.
"""
@ -105,7 +105,7 @@ class ContainerTree:
def __getitem__(self, definition_id: str) -> MachineNode:
"""Returns a machine node for the specified definition ID.
If the machine node wasn't loaded yet, this will load it lazily.
:param definition_id: The definition to look for.
@ -122,7 +122,7 @@ class ContainerTree:
def get(self, definition_id: str, default: Optional[MachineNode] = None) -> Optional[MachineNode]:
"""Gets a machine node for the specified definition ID, with default.
The default is returned if there is no definition with the specified ID. If the machine node wasn't
loaded yet, this will load it lazily.
@ -140,7 +140,7 @@ class ContainerTree:
def is_loaded(self, definition_id: str) -> bool:
"""Returns whether we've already cached this definition's node.
:param definition_id: The definition that we may have cached.
:return: ``True`` if it's cached.
@ -155,7 +155,7 @@ class ContainerTree:
def __init__(self, tree_root: "ContainerTree", container_stacks: List["ContainerStack"]) -> None:
"""Creates a new background task.
:param tree_root: The container tree instance. This cannot be obtained through the singleton static
function since the instance may not yet be constructed completely.
:param container_stacks: All of the stacks to pre-load the container trees for. This needs to be provided
@ -168,7 +168,7 @@ class ContainerTree:
def run(self) -> None:
"""Starts the background task.
The ``JobQueue`` will schedule this on a different thread.
"""

View file

@ -13,7 +13,7 @@ if TYPE_CHECKING:
class IntentNode(ContainerNode):
"""This class represents an intent profile in the container tree.
This class has no more subnodes.
"""

View file

@ -19,7 +19,7 @@ import UM.FlameProfiler
class MachineNode(ContainerNode):
"""This class represents a machine in the container tree.
The subnodes of these nodes are variants.
"""
@ -51,7 +51,7 @@ class MachineNode(ContainerNode):
def getQualityGroups(self, variant_names: List[str], material_bases: List[str], extruder_enabled: List[bool]) -> Dict[str, QualityGroup]:
"""Get the available quality groups for this machine.
This returns all quality groups, regardless of whether they are available to the combination of extruders or
not. On the resulting quality groups, the is_available property is set to indicate whether the quality group
can be selected according to the combination of extruders in the parameters.
@ -103,13 +103,13 @@ class MachineNode(ContainerNode):
def getQualityChangesGroups(self, variant_names: List[str], material_bases: List[str], extruder_enabled: List[bool]) -> List[QualityChangesGroup]:
"""Returns all of the quality changes groups available to this printer.
The quality changes groups store which quality type and intent category they were made for, but not which
material and nozzle. Instead for the quality type and intent category, the quality changes will always be
available but change the quality type and intent category when activated.
The quality changes group does depend on the printer: Which quality definition is used.
The quality changes groups that are available do depend on the quality types that are available, so it must
still be known which extruders are enabled and which materials and variants are loaded in them. This allows
setting the correct is_available flag.
@ -150,7 +150,7 @@ class MachineNode(ContainerNode):
def preferredGlobalQuality(self) -> "QualityNode":
"""Gets the preferred global quality node, going by the preferred quality type.
If the preferred global quality is not in there, an arbitrary global quality is taken. If there are no global
qualities, an empty quality is returned.
"""

View file

@ -9,17 +9,17 @@ if TYPE_CHECKING:
class MaterialGroup:
"""A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile.
The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For
example: "generic_abs" is the root material (ID) of "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4",
and "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4" are derived materials of "generic_abs".
Using "generic_abs" as an example, the MaterialGroup for "generic_abs" will contain the following information:
- name: "generic_abs", root_material_id
- root_material_node: MaterialNode of "generic_abs"
- derived_material_node_list: A list of MaterialNodes that are derived from "generic_abs", so
"generic_abs_ultimaker3", "generic_abs_ultimaker3_AA_0.4", etc.
"""
__slots__ = ("name", "is_read_only", "root_material_node", "derived_material_node_list")

View file

@ -17,7 +17,7 @@ if TYPE_CHECKING:
class MaterialNode(ContainerNode):
"""Represents a material in the container tree.
Its subcontainers are quality profiles.
"""
@ -38,7 +38,7 @@ class MaterialNode(ContainerNode):
def preferredQuality(self) -> QualityNode:
"""Finds the preferred quality for this printer with this material and this variant loaded.
If the preferred quality is not available, an arbitrary quality is returned. If there is a configuration
mistake (like a typo in the preferred quality) this returns a random available quality. If there are no
available qualities, this will return the empty quality node.

View file

@ -15,7 +15,7 @@ from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
class BaseMaterialsModel(ListModel):
"""This is the base model class for GenericMaterialsModel and MaterialBrandsModel.
Those 2 models are used by the material drop down menu to show generic materials and branded materials
separately. The extruder position defined here is being used to bound a menu to the correct extruder. This is
used in the top bar menu "Settings" -> "Extruder nr" -> "Material" -> this menu
@ -125,7 +125,7 @@ class BaseMaterialsModel(ListModel):
def _materialsListChanged(self, material: MaterialNode) -> None:
"""Triggered when a list of materials changed somewhere in the container
tree. This change may trigger an _update() call when the materials changed for the configuration that this
model is looking for.
"""

View file

@ -212,7 +212,7 @@ class DiscoveredPrintersModel(QObject):
@pyqtProperty("QVariantMap", notify = discoveredPrintersChanged)
def discoveredPrintersByAddress(self) -> Dict[str, DiscoveredPrinter]:
return self._discovered_printer_by_ip_dict
@pyqtProperty("QVariantList", notify = discoveredPrintersChanged)
def discoveredPrinters(self) -> List["DiscoveredPrinter"]:
item_list = list(

View file

@ -17,7 +17,7 @@ catalog = i18nCatalog("cura")
class ExtrudersModel(ListModel):
"""Model that holds extruders.
This model is designed for use by any list of extruders, but specifically intended for drop-down lists of the
current machine's extruders in place of settings.
"""
@ -33,7 +33,7 @@ class ExtrudersModel(ListModel):
IndexRole = Qt.UserRole + 4
"""Index of the extruder, which is also the value of the setting itself.
An index of 0 indicates the first extruder, an index of 1 the second one, and so on. This is the value that will
be saved in instance containers. """
@ -58,7 +58,7 @@ class ExtrudersModel(ListModel):
def __init__(self, parent = None):
"""Initialises the extruders model, defining the roles and listening for changes in the data.
:param parent: Parent QtObject of this list.
"""
@ -104,7 +104,7 @@ class ExtrudersModel(ListModel):
def _extrudersChanged(self, machine_id = None):
"""Links to the stack-changed signal of the new extruders when an extruder is swapped out or added in the
current machine.
:param machine_id: The machine for which the extruders changed. This is filled by the
ExtruderManager.extrudersChanged signal when coming from that signal. Application.globalContainerStackChanged
doesn't fill this signal; it's assumed to be the current printer in that case.
@ -150,7 +150,7 @@ class ExtrudersModel(ListModel):
@UM.FlameProfiler.profile
def __updateExtruders(self):
"""Update the list of extruders.
This should be called whenever the list of extruders changes.
"""

View file

@ -57,7 +57,7 @@ class IntentCategoryModel(ListModel):
def __init__(self, intent_category: str) -> None:
"""Creates a new model for a certain intent category.
:param intent_category: category to list the intent profiles for.
"""

View file

@ -21,20 +21,20 @@ catalog = i18nCatalog("cura")
class MaterialManagementModel(QObject):
"""Proxy class to the materials page in the preferences.
This class handles the actions in that page, such as creating new materials, renaming them, etc.
"""
favoritesChanged = pyqtSignal(str)
"""Triggered when a favorite is added or removed.
:param The base file of the material is provided as parameter when this emits
"""
@pyqtSlot("QVariant", result = bool)
def canMaterialBeRemoved(self, material_node: "MaterialNode") -> bool:
"""Can a certain material be deleted, or is it still in use in one of the container stacks anywhere?
We forbid the user from deleting a material if it's in use in any stack. Deleting it while it's in use can
lead to corrupted stacks. In the future we might enable this functionality again (deleting the material from
those stacks) but for now it is easier to prevent the user from doing this.
@ -54,7 +54,7 @@ class MaterialManagementModel(QObject):
@pyqtSlot("QVariant", str)
def setMaterialName(self, material_node: "MaterialNode", name: str) -> None:
"""Change the user-visible name of a material.
:param material_node: The ContainerTree node of the material to rename.
:param name: The new name for the material.
"""
@ -69,7 +69,7 @@ class MaterialManagementModel(QObject):
@pyqtSlot("QVariant")
def removeMaterial(self, material_node: "MaterialNode") -> None:
"""Deletes a material from Cura.
This function does not do any safety checking any more. Please call this function only if:
- The material is not read-only.
- The material is not used in any stacks.
@ -200,7 +200,7 @@ class MaterialManagementModel(QObject):
def createMaterial(self) -> str:
"""Create a new material by cloning the preferred material for the current material diameter and generate a new
GUID.
The material type is explicitly left to be the one from the preferred material, since this allows the user to
still have SOME profiles to work with.
@ -234,7 +234,7 @@ class MaterialManagementModel(QObject):
@pyqtSlot(str)
def addFavorite(self, material_base_file: str) -> None:
"""Adds a certain material to the favorite materials.
:param material_base_file: The base file of the material to add.
"""
@ -249,7 +249,7 @@ class MaterialManagementModel(QObject):
@pyqtSlot(str)
def removeFavorite(self, material_base_file: str) -> None:
"""Removes a certain material from the favorite materials.
If the material was not in the favorite materials, nothing happens.
"""

View file

@ -76,7 +76,7 @@ class QualityManagementModel(ListModel):
@pyqtSlot(QObject)
def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None:
"""Deletes a custom profile. It will be gone forever.
:param quality_changes_group: The quality changes group representing the profile to delete.
"""
@ -99,7 +99,7 @@ class QualityManagementModel(ListModel):
@pyqtSlot(QObject, str, result = str)
def renameQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", new_name: str) -> str:
"""Rename a custom profile.
Because the names must be unique, the new name may not actually become the name that was given. The actual
name is returned by this function.
@ -145,7 +145,7 @@ class QualityManagementModel(ListModel):
@pyqtSlot(str, "QVariantMap")
def duplicateQualityChanges(self, new_name: str, quality_model_item: Dict[str, Any]) -> None:
"""Duplicates a given quality profile OR quality changes profile.
:param new_name: The desired name of the new profile. This will be made unique, so it might end up with a
different name.
:param quality_model_item: The item of this model to duplicate, as dictionary. See the descriptions of the
@ -180,7 +180,7 @@ class QualityManagementModel(ListModel):
@pyqtSlot(str)
def createQualityChanges(self, base_name: str) -> None:
"""Create quality changes containers from the user containers in the active stacks.
This will go through the global and extruder stacks and create quality_changes containers from the user
containers in each stack. These then replace the quality_changes containers in the stack and clear the user
settings.
@ -229,7 +229,7 @@ class QualityManagementModel(ListModel):
def _createQualityChanges(self, quality_type: str, intent_category: Optional[str], new_name: str, machine: "GlobalStack", extruder_stack: Optional["ExtruderStack"]) -> "InstanceContainer":
"""Create a quality changes container with the given set-up.
:param quality_type: The quality type of the new container.
:param intent_category: The intent category of the new container.
:param new_name: The name of the container. This name must be unique.
@ -264,7 +264,7 @@ class QualityManagementModel(ListModel):
def _qualityChangesListChanged(self, container: "ContainerInterface") -> None:
"""Triggered when any container changed.
This filters the updates to the container manager: When it applies to the list of quality changes, we need to
update our list.
"""
@ -383,7 +383,7 @@ class QualityManagementModel(ListModel):
The convenience meta-filters "All Supported Types" and "All Files" are added when listing readers,
but not when listing writers.
:param io_type: name of the needed IO type
:return: A list of strings indicating file name filters for a file dialog.
@ -408,7 +408,7 @@ class QualityManagementModel(ListModel):
def _getIOPlugins(self, io_type):
"""Gets a list of profile reader or writer plugins
:return: List of tuples of (plugin_id, meta_data).
"""
from UM.PluginRegistry import PluginRegistry

View file

@ -8,7 +8,7 @@ from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
class QualityChangesGroup(QObject):
"""Data struct to group several quality changes instance containers together.
Each group represents one "custom profile" as the user sees it, which contains an instance container for the
global stack and one instance container per extruder.
"""

View file

@ -12,7 +12,7 @@ from cura.Machines.ContainerNode import ContainerNode
class QualityGroup:
"""A QualityGroup represents a group of quality containers that must be applied to each ContainerStack when it's
used.
A concrete example: When there are two extruders and the user selects the quality type "normal", this quality
type must be applied to all stacks in a machine, although each stack can have different containers. So one global
profile gets put on the global stack and one extruder profile gets put on each extruder stack. This quality group
@ -24,7 +24,7 @@ class QualityGroup:
- um3_global_normal
- um3_aa04_pla_normal
- um3_aa04_abs_normal
The purpose of these quality groups is to group the containers that can be applied to a configuration,
so that when a quality level is selected, the container can directly be applied to each stack instead of looking
them up again.
@ -32,7 +32,7 @@ class QualityGroup:
def __init__(self, name: str, quality_type: str) -> None:
"""Constructs a new group.
:param name: The user-visible name for the group.
:param quality_type: The quality level that each profile in this group has.
"""

View file

@ -15,9 +15,9 @@ if TYPE_CHECKING:
class QualityNode(ContainerNode):
"""Represents a quality profile in the container tree.
This may either be a normal quality profile or a global quality profile.
Its subcontainers are intent profiles.
"""

View file

@ -19,9 +19,9 @@ if TYPE_CHECKING:
class VariantNode(ContainerNode):
"""This class represents an extruder variant in the container tree.
The subnodes of these nodes are materials.
This node contains materials with ALL filament diameters underneath it. The tree of this variant is not specific
to one global stack, so because the list of materials can be different per stack depending on the compatible
material diameter setting, we cannot filter them here. Filtering must be done in the model.
@ -72,7 +72,7 @@ class VariantNode(ContainerNode):
def preferredMaterial(self, approximate_diameter: int) -> MaterialNode:
"""Finds the preferred material for this printer with this nozzle in one of the extruders.
If the preferred material is not available, an arbitrary material is returned. If there is a configuration
mistake (like a typo in the preferred material) this returns a random available material. If there are no
available materials, this will return the empty material node.
@ -85,14 +85,14 @@ class VariantNode(ContainerNode):
for base_material, material_node in self.materials.items():
if self.machine.preferred_material == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
return material_node
# First fallback: Check if we should be checking for the 175 variant.
if approximate_diameter == 2:
preferred_material = self.machine.preferred_material + "_175"
for base_material, material_node in self.materials.items():
if preferred_material == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
return material_node
# Second fallback: Choose any material with matching diameter.
for material_node in self.materials.values():
if material_node.getMetaDataEntry("approximate_diameter") and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):

View file

@ -31,12 +31,12 @@ class AuthorizationHelpers:
def getAccessTokenUsingAuthorizationCode(self, authorization_code: str, verification_code: str) -> "AuthenticationResponse":
"""Request the access token from the authorization server.
:param authorization_code: The authorization code from the 1st step.
:param verification_code: The verification code needed for the PKCE extension.
:return: An AuthenticationResponse object.
"""
data = {
"client_id": self._settings.CLIENT_ID if self._settings.CLIENT_ID is not None else "",
"redirect_uri": self._settings.CALLBACK_URL if self._settings.CALLBACK_URL is not None else "",
@ -52,11 +52,11 @@ class AuthorizationHelpers:
def getAccessTokenUsingRefreshToken(self, refresh_token: str) -> "AuthenticationResponse":
"""Request the access token from the authorization server using a refresh token.
:param refresh_token:
:return: An AuthenticationResponse object.
"""
Logger.log("d", "Refreshing the access token.")
data = {
"client_id": self._settings.CLIENT_ID if self._settings.CLIENT_ID is not None else "",
@ -73,11 +73,11 @@ class AuthorizationHelpers:
@staticmethod
def parseTokenResponse(token_response: requests.models.Response) -> "AuthenticationResponse":
"""Parse the token response from the authorization server into an AuthenticationResponse object.
:param token_response: The JSON string data response from the authorization server.
:return: An AuthenticationResponse object.
"""
token_data = None
try:
@ -101,11 +101,11 @@ class AuthorizationHelpers:
def parseJWT(self, access_token: str) -> Optional["UserProfile"]:
"""Calls the authentication API endpoint to get the token data.
:param access_token: The encoded JWT token.
:return: Dict containing some profile data.
"""
try:
token_request = requests.get("{}/check-token".format(self._settings.OAUTH_SERVER_URL), headers = {
"Authorization": "Bearer {}".format(access_token)
@ -130,20 +130,20 @@ class AuthorizationHelpers:
@staticmethod
def generateVerificationCode(code_length: int = 32) -> str:
"""Generate a verification code of arbitrary length.
:param code_length:: How long should the code be? This should never be lower than 16, but it's probably
better to leave it at 32
"""
return "".join(random.choice("0123456789ABCDEF") for i in range(code_length))
@staticmethod
def generateVerificationCodeChallenge(verification_code: str) -> str:
"""Generates a base64 encoded sha512 encrypted version of a given string.
:param verification_code:
:return: The encrypted code in base64 format.
"""
encoded = sha512(verification_code.encode()).digest()
return b64encode(encoded, altchars = b"_-").decode()

View file

@ -16,10 +16,10 @@ catalog = i18nCatalog("cura")
class AuthorizationRequestHandler(BaseHTTPRequestHandler):
"""This handler handles all HTTP requests on the local web server.
It also requests the access token for the 2nd stage of the OAuth flow.
"""
def __init__(self, request, client_address, server) -> None:
super().__init__(request, client_address, server)
@ -60,11 +60,11 @@ class AuthorizationRequestHandler(BaseHTTPRequestHandler):
def _handleCallback(self, query: Dict[Any, List]) -> Tuple[ResponseData, Optional[AuthenticationResponse]]:
"""Handler for the callback URL redirect.
:param query: Dict containing the HTTP query parameters.
:return: HTTP ResponseData containing a success page to show to the user.
"""
code = self._queryGet(query, "code")
state = self._queryGet(query, "state")
if state != self.state:

View file

@ -11,11 +11,11 @@ if TYPE_CHECKING:
class AuthorizationRequestServer(HTTPServer):
"""The authorization request callback handler server.
This subclass is needed to be able to pass some data to the request handler. This cannot be done on the request
handler directly as the HTTPServer creates an instance of the handler after init.
"""
def setAuthorizationHelpers(self, authorization_helpers: "AuthorizationHelpers") -> None:
"""Set the authorization helpers instance on the request handler."""

View file

@ -251,7 +251,7 @@ class AuthorizationService:
if self._preferences is None:
Logger.log("e", "Unable to save authentication data, since no preference has been set!")
return
self._auth_data = auth_data
if auth_data:
self._user_profile = self.getUserProfile()

View file

@ -24,19 +24,19 @@ class LocalAuthorizationServer:
auth_state_changed_callback: Callable[["AuthenticationResponse"], Any],
daemon: bool) -> None:
"""The local LocalAuthorizationServer takes care of the oauth2 callbacks.
Once the flow is completed, this server should be closed down again by calling
:py:meth:`cura.OAuth2.LocalAuthorizationServer.LocalAuthorizationServer.stop()`
:param auth_helpers: An instance of the authorization helpers class.
:param auth_state_changed_callback: A callback function to be called when the authorization state changes.
:param daemon: Whether the server thread should be run in daemon mode.
.. note::
Daemon threads are abruptly stopped at shutdown. Their resources (e.g. open files) may never be released.
"""
self._web_server = None # type: Optional[AuthorizationRequestServer]
self._web_server_thread = None # type: Optional[threading.Thread]
self._web_server_port = auth_helpers.settings.CALLBACK_PORT
@ -46,11 +46,11 @@ class LocalAuthorizationServer:
def start(self, verification_code: str, state: str) -> None:
"""Starts the local web server to handle the authorization callback.
:param verification_code: The verification code part of the OAuth2 client identification.
:param state: The unique state code (to ensure that the request we get back is really from the server.
"""
if self._web_server:
# If the server is already running (because of a previously aborted auth flow), we don't have to start it.
# We still inject the new verification code though.

View file

@ -9,7 +9,7 @@ from functools import cmp_to_key
class OneAtATimeIterator(Iterator.Iterator):
"""Iterator that returns a list of nodes in the order that they need to be printed
If there is no solution an empty list is returned.
Take note that the list of nodes can have children (that may or may not contain mesh data)
"""
@ -80,7 +80,7 @@ class OneAtATimeIterator(Iterator.Iterator):
def _checkBlockMultiple(self, node: SceneNode, other_nodes: List[SceneNode]) -> bool:
"""Check for a node whether it hits any of the other nodes.
:param node: The node to check whether it collides with the other nodes.
:param other_nodes: The nodes to check for collisions.
:return: returns collision between nodes
@ -140,7 +140,7 @@ class _ObjectOrder:
def __init__(self, order: List[SceneNode], todo: List[SceneNode]) -> None:
"""Creates the _ObjectOrder instance.
:param order: List of indices in which to print objects, ordered by printing order.
:param todo: List of indices which are not yet inserted into the order list.
"""

View file

@ -11,7 +11,7 @@ class SetParentOperation(Operation.Operation):
def __init__(self, node: SceneNode, parent_node: Optional[SceneNode]) -> None:
"""Initialises this SetParentOperation.
:param node: The node which will be reparented.
:param parent_node: The node which will be the parent.
"""
@ -33,7 +33,7 @@ class SetParentOperation(Operation.Operation):
def _set_parent(self, new_parent: Optional[SceneNode]) -> None:
"""Sets the parent of the node while applying transformations to the world-transform of the node stays the same.
:param new_parent: The new parent. Note: this argument can be None, which would hide the node from the scene.
"""
@ -64,7 +64,7 @@ class SetParentOperation(Operation.Operation):
def __repr__(self) -> str:
"""Returns a programmer-readable representation of this operation.
:return: A programmer-readable representation of this operation.
"""

View file

@ -21,9 +21,9 @@ if TYPE_CHECKING:
class PickingPass(RenderPass):
"""A :py:class:`Uranium.UM.View.RenderPass` subclass that renders a the distance of selectable objects from the
active camera to a texture.
The texture is used to map a 2d location (eg the mouse location) to a world space position
.. note:: that in order to increase precision, the 24 bit depth value is encoded into all three of the R,G & B channels
"""

View file

@ -95,15 +95,15 @@ class PlatformPhysics:
# Ignore root, ourselves and anything that is not a normal SceneNode.
if other_node is root or not issubclass(type(other_node), SceneNode) or other_node is node or other_node.callDecoration("getBuildPlateNumber") != node.callDecoration("getBuildPlateNumber"):
continue
# Ignore collisions of a group with it's own children
if other_node in node.getAllChildren() or node in other_node.getAllChildren():
continue
# Ignore collisions within a group
if other_node.getParent() and node.getParent() and (other_node.getParent().callDecoration("isGroup") is not None or node.getParent().callDecoration("isGroup") is not None):
continue
# Ignore nodes that do not have the right properties set.
if not other_node.callDecoration("getConvexHull") or not other_node.getBoundingBox():
continue

View file

@ -39,9 +39,9 @@ def prettier_color(color_list: List[float]) -> List[float]:
class PreviewPass(RenderPass):
"""A :py:class:`Uranium.UM.View.RenderPass` subclass that renders slicable objects with default parameters.
It uses the active camera by default, but it can be overridden to use a different camera.
This is useful to get a preview image of a scene taken from a different location as the active camera.
"""

View file

@ -36,7 +36,7 @@ class FirmwareUpdater(QObject):
if self._firmware_file == "":
self._setFirmwareUpdateState(FirmwareUpdateState.firmware_not_found_error)
return
self._setFirmwareUpdateState(FirmwareUpdateState.updating)
self._update_firmware_thread.start()

View file

@ -49,7 +49,7 @@ class ExtruderConfigurationModel(QObject):
def isValid(self) -> bool:
"""This method is intended to indicate whether the configuration is valid or not.
The method checks if the mandatory fields are or not set
At this moment is always valid since we allow to have empty material and variants.
"""

View file

@ -106,7 +106,7 @@ class ExtruderOutputModel(QObject):
@pyqtSlot(float, float)
def preheatHotend(self, temperature: float, duration: float) -> None:
"""Pre-heats the extruder before printer.
:param temperature: The temperature to heat the extruder to, in degrees
Celsius.
:param duration: How long the bed should stay warm, in seconds.

View file

@ -50,7 +50,7 @@ class PrinterConfigurationModel(QObject):
def isValid(self) -> bool:
"""This method is intended to indicate whether the configuration is valid or not.
The method checks if the mandatory fields are or not set
"""
if not self._extruder_configurations:
@ -101,7 +101,7 @@ class PrinterConfigurationModel(QObject):
def __hash__(self):
"""The hash function is used to compare and create unique sets. The configuration is unique if the configuration
of the extruders is unique (the order of the extruders matters), and the type and buildplate is the same.
"""
extruder_hash = hash(0)

View file

@ -166,7 +166,7 @@ class PrinterOutputModel(QObject):
@pyqtSlot(float, float)
def preheatBed(self, temperature: float, duration: float) -> None:
"""Pre-heats the heated bed of the printer.
:param temperature: The temperature to heat the bed to, in degrees
Celsius.
:param duration: How long the bed should stay warm, in seconds.

View file

@ -147,7 +147,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def createFormPart(self, content_header: str, data: bytes, content_type: Optional[str] = None) -> QHttpPart:
"""This method was only available privately before, but it was actually called from SendMaterialJob.py.
We now have a public equivalent as well. We did not remove the private one as plugins might be using that.
"""
return self._createFormPart(content_header, data, content_type)
@ -194,7 +194,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
on_finished: Optional[Callable[[QNetworkReply], None]] = None,
on_progress: Optional[Callable[[int, int], None]] = None) -> None:
"""Sends a put request to the given path.
:param url: The path after the API prefix.
:param data: The data to be sent in the body
:param content_type: The content type of the body data.
@ -219,7 +219,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def delete(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
"""Sends a delete request to the given path.
:param url: The path after the API prefix.
:param on_finished: The function to be call when the response is received.
"""
@ -237,7 +237,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def get(self, url: str, on_finished: Optional[Callable[[QNetworkReply], None]]) -> None:
"""Sends a get request to the given path.
:param url: The path after the API prefix.
:param on_finished: The function to be call when the response is received.
"""
@ -258,7 +258,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
on_progress: Optional[Callable[[int, int], None]] = None) -> None:
"""Sends a post request to the given path.
:param url: The path after the API prefix.
:param data: The data to be sent in the body
:param on_finished: The function to call when the response is received.
@ -333,7 +333,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
def _checkCorrectGroupName(self, device_id: str, group_name: str) -> None:
"""This method checks if the name of the group stored in the definition container is correct.
After updating from 3.2 to 3.3 some group names may be temporary. If there is a mismatch in the name of the group
then all the container stacks are updated, both the current and the hidden ones.
"""
@ -385,7 +385,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
@pyqtProperty(str, constant = True)
def key(self) -> str:
"""Get the unique key of this machine
:return: key String containing the key of the machine.
"""
return self._id

View file

@ -4,7 +4,7 @@
class Peripheral:
"""Data class that represents a peripheral for a printer.
Output device plug-ins may specify that the printer has a certain set of
peripherals. This set is then possibly shown in the interface of the monitor
stage.
@ -12,7 +12,7 @@ class Peripheral:
def __init__(self, peripheral_type: str, name: str) -> None:
"""Constructs the peripheral.
:param peripheral_type: A unique ID for the type of peripheral.
:param name: A human-readable name for the peripheral.
"""

View file

@ -44,13 +44,13 @@ class ConnectionType(IntEnum):
@signalemitter
class PrinterOutputDevice(QObject, OutputDevice):
"""Printer output device adds extra interface options on top of output device.
The assumption is made the printer is a FDM printer.
Note that a number of settings are marked as "final". This is because decorators
are not inherited by children. To fix this we use the private counter part of those
functions to actually have the implementation.
For all other uses it should be used in the same way as a "regular" OutputDevice.
"""
@ -250,7 +250,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
def _setFirmwareName(self, name: str) -> None:
"""Set the device firmware name
:param name: The name of the firmware.
"""
@ -258,7 +258,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
def getFirmwareName(self) -> Optional[str]:
"""Get the name of device firmware
This name can be used to define device type
"""

View file

@ -12,7 +12,7 @@ class NoProfileException(Exception):
class ProfileReader(PluginObject):
"""A type of plug-ins that reads profiles from a file.
The profile is then stored as instance container of the type user profile.
"""
@ -21,7 +21,7 @@ class ProfileReader(PluginObject):
def read(self, file_name):
"""Read profile data from a file and return a filled profile.
:return: :type{Profile|Profile[]} The profile that was obtained from the file or a list of Profiles.
"""

View file

@ -6,13 +6,13 @@ from UM.PluginObject import PluginObject
class ProfileWriter(PluginObject):
"""Base class for profile writer plugins.
This class defines a write() function to write profiles to files with.
"""
def __init__(self):
"""Initialises the profile writer.
This currently doesn't do anything since the writer is basically static.
"""
@ -20,9 +20,9 @@ class ProfileWriter(PluginObject):
def write(self, path, profiles):
"""Writes a profile to the specified file path.
The profile writer may write its own file format to the specified file.
:param path: :type{string} The file to output to.
:param profiles: :type{Profile} or :type{List} The profile(s) to write to the file.
:return: True if the writing was successful, or False if it wasn't.

View file

@ -25,7 +25,7 @@ if TYPE_CHECKING:
class ConvexHullDecorator(SceneNodeDecorator):
"""The convex hull decorator is a scene node decorator that adds the convex hull functionality to a scene node.
If a scene node has a convex hull decorator, it will have a shadow in which other objects can not be printed.
"""
@ -84,7 +84,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def getAdhesionArea(self) -> Optional[Polygon]:
"""The polygon representing the 2D adhesion area.
If no adhesion is used, the regular convex hull is returned
"""
if self._node is None:
@ -98,7 +98,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def getConvexHull(self) -> Optional[Polygon]:
"""Get the unmodified 2D projected convex hull of the node (if any)
In case of one-at-a-time, this includes adhesion and head+fans clearance
"""
if self._node is None:
@ -118,7 +118,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def getConvexHullHeadFull(self) -> Optional[Polygon]:
"""For one at the time this is the convex hull of the node with the full head size
In case of printing all at once this is None.
"""
if self._node is None:
@ -138,7 +138,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def getConvexHullHead(self) -> Optional[Polygon]:
"""Get convex hull of the object + head size
In case of printing all at once this is None.
For one at the time this is area with intersection of mirrored head
"""
@ -156,7 +156,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def getConvexHullBoundary(self) -> Optional[Polygon]:
"""Get convex hull of the node
In case of printing all at once this None??
For one at the time this is the area without the head.
"""
@ -173,7 +173,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def getPrintingArea(self) -> Optional[Polygon]:
"""Get the buildplate polygon where will be printed
In case of printing all at once this is the same as convex hull (no individual adhesion)
For one at the time this includes the adhesion area
"""
@ -344,7 +344,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def _add2DAdhesionMargin(self, poly: Polygon) -> Polygon:
"""Compensate given 2D polygon with adhesion margin
:return: 2D polygon with added margin
"""
if not self._global_stack:
@ -379,7 +379,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
def _offsetHull(self, convex_hull: Polygon) -> Polygon:
"""Offset the convex hull with settings that influence the collision area.
:param convex_hull: Polygon of the original convex hull.
:return: New Polygon instance that is offset with everything that
influences the collision area.
@ -476,6 +476,6 @@ class ConvexHullDecorator(SceneNodeDecorator):
_influencing_settings = {"xy_offset", "xy_offset_layer_0", "mold_enabled", "mold_width", "anti_overhang_mesh", "infill_mesh", "cutting_mesh"}
"""Settings that change the convex hull.
If these settings change, the convex hull should be recalculated.
"""

View file

@ -20,7 +20,7 @@ class ConvexHullNode(SceneNode):
def __init__(self, node: SceneNode, hull: Optional[Polygon], thickness: float, parent: Optional[SceneNode] = None) -> None:
"""Convex hull node is a special type of scene node that is used to display an area, to indicate the
location an object uses on the buildplate. This area (or area's in case of one at a time printing) is
then displayed as a transparent shadow. If the adhesion type is set to raft, the area is extruded
to represent the raft as well.

View file

@ -17,7 +17,7 @@ from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator # F
class CuraSceneNode(SceneNode):
"""Scene nodes that are models are only seen when selecting the corresponding build plate
Note that many other nodes can just be UM SceneNode objects.
"""
def __init__(self, parent: Optional["SceneNode"] = None, visible: bool = True, name: str = "", no_setting_override: bool = False) -> None:
@ -40,7 +40,7 @@ class CuraSceneNode(SceneNode):
def getPrintingExtruder(self) -> Optional[ExtruderStack]:
"""Get the extruder used to print this node. If there is no active node, then the extruder in position zero is returned
TODO The best way to do it is by adding the setActiveExtruder decorator to every node when is loaded
"""
global_container_stack = Application.getInstance().getGlobalContainerStack()

View file

@ -4,7 +4,7 @@ from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
class SliceableObjectDecorator(SceneNodeDecorator):
def __init__(self) -> None:
super().__init__()
def isSliceable(self) -> bool:
return True

View file

@ -35,7 +35,7 @@ catalog = i18nCatalog("cura")
class ContainerManager(QObject):
"""Manager class that contains common actions to deal with containers in Cura.
This is primarily intended as a class to be able to perform certain actions
from within QML. We want to be able to trigger things like removing a container
when a certain action happens. This can be done through this class.
@ -72,16 +72,16 @@ class ContainerManager(QObject):
@pyqtSlot("QVariant", str, str)
def setContainerMetaDataEntry(self, container_node: "ContainerNode", entry_name: str, entry_value: str) -> bool:
"""Set a metadata entry of the specified container.
This will set the specified entry of the container's metadata to the specified
value. Note that entries containing dictionaries can have their entries changed
by using "/" as a separator. For example, to change an entry "foo" in a
dictionary entry "bar", you can specify "bar/foo" as entry name.
:param container_node: :type{ContainerNode}
:param entry_name: :type{str} The name of the metadata entry to change.
:param entry_value: The new value of the entry.
TODO: This is ONLY used by MaterialView for material containers. Maybe refactor this.
Update: In order for QML to use objects and sub objects, those (sub) objects must all be QObject. Is that what we want?
"""
@ -131,14 +131,14 @@ class ContainerManager(QObject):
@pyqtSlot(str, result = "QStringList")
def getContainerNameFilters(self, type_name: str) -> List[str]:
"""Get a list of string that can be used as name filters for a Qt File Dialog
This will go through the list of available container types and generate a list of strings
out of that. The strings are formatted as "description (*.extension)" and can be directly
passed to a nameFilters property of a Qt File Dialog.
:param type_name: Which types of containers to list. These types correspond to the "type"
key of the plugin metadata.
:return: A string list with name filters.
"""
@ -156,11 +156,11 @@ class ContainerManager(QObject):
@pyqtSlot(str, str, QUrl, result = "QVariantMap")
def exportContainer(self, container_id: str, file_type: str, file_url_or_string: Union[QUrl, str]) -> Dict[str, str]:
"""Export a container to a file
:param container_id: The ID of the container to export
:param file_type: The type of file to save as. Should be in the form of "description (*.extension, *.ext)"
:param file_url_or_string: The URL where to save the file.
:return: A dictionary containing a key "status" with a status code and a key "message" with a message
explaining the status. The status code can be one of "error", "cancelled", "success"
"""
@ -224,9 +224,9 @@ class ContainerManager(QObject):
@pyqtSlot(QUrl, result = "QVariantMap")
def importMaterialContainer(self, file_url_or_string: Union[QUrl, str]) -> Dict[str, str]:
"""Imports a profile from a file
:param file_url: A URL that points to the file to import.
:return: :type{Dict} dict with a 'status' key containing the string 'success' or 'error', and a 'message' key
containing a message for the user
"""
@ -278,10 +278,10 @@ class ContainerManager(QObject):
@pyqtSlot(result = bool)
def updateQualityChanges(self) -> bool:
"""Update the current active quality changes container with the settings from the user container.
This will go through the active global stack and all active extruder stacks and merge the changes from the user
container into the quality_changes container. After that, the user container is cleared.
:return: :type{bool} True if successful, False if not.
"""
@ -350,7 +350,7 @@ class ContainerManager(QObject):
@pyqtSlot("QVariant", bool, result = "QStringList")
def getLinkedMaterials(self, material_node: "MaterialNode", exclude_self: bool = False) -> List[str]:
"""Get a list of materials that have the same GUID as the reference material
:param material_node: The node representing the material for which to get
the same GUID.
:param exclude_self: Whether to include the name of the material you provided.
@ -366,7 +366,7 @@ class ContainerManager(QObject):
@pyqtSlot("QVariant")
def unlinkMaterial(self, material_node: "MaterialNode") -> None:
"""Unlink a material from all other materials by creating a new GUID
:param material_id: :type{str} the id of the material to create a new GUID for.
"""
# Get the material group

View file

@ -20,11 +20,11 @@ from . import Exceptions
class CuraContainerStack(ContainerStack):
"""Base class for Cura related stacks that want to enforce certain containers are available.
This class makes sure that the stack has the following containers set: user changes, quality
changes, quality, material, variant, definition changes and finally definition. Initially,
these will be equal to the empty instance container.
The container types are determined based on the following criteria:
- user: An InstanceContainer with the metadata entry "type" set to "user".
- quality changes: An InstanceContainer with the metadata entry "type" set to "quality_changes".
@ -33,7 +33,7 @@ class CuraContainerStack(ContainerStack):
- variant: An InstanceContainer with the metadata entry "type" set to "variant".
- definition changes: An InstanceContainer with the metadata entry "type" set to "definition_changes".
- definition: A DefinitionContainer.
Internally, this class ensures the mentioned containers are always there and kept in a specific order.
This also means that operations on the stack that modifies the container ordering is prohibited and
will raise an exception.
@ -65,7 +65,7 @@ class CuraContainerStack(ContainerStack):
def setUserChanges(self, new_user_changes: InstanceContainer) -> None:
"""Set the user changes container.
:param new_user_changes: The new user changes container. It is expected to have a "type" metadata entry with the value "user".
"""
@ -74,7 +74,7 @@ class CuraContainerStack(ContainerStack):
@pyqtProperty(InstanceContainer, fset = setUserChanges, notify = pyqtContainersChanged)
def userChanges(self) -> InstanceContainer:
"""Get the user changes container.
:return: The user changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
"""
@ -82,7 +82,7 @@ class CuraContainerStack(ContainerStack):
def setQualityChanges(self, new_quality_changes: InstanceContainer, postpone_emit = False) -> None:
"""Set the quality changes container.
:param new_quality_changes: The new quality changes container. It is expected to have a "type" metadata entry with the value "quality_changes".
"""
@ -91,7 +91,7 @@ class CuraContainerStack(ContainerStack):
@pyqtProperty(InstanceContainer, fset = setQualityChanges, notify = pyqtContainersChanged)
def qualityChanges(self) -> InstanceContainer:
"""Get the quality changes container.
:return: The quality changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
"""
@ -99,7 +99,7 @@ class CuraContainerStack(ContainerStack):
def setIntent(self, new_intent: InstanceContainer, postpone_emit: bool = False) -> None:
"""Set the intent container.
:param new_intent: The new intent container. It is expected to have a "type" metadata entry with the value "intent".
"""
@ -108,7 +108,7 @@ class CuraContainerStack(ContainerStack):
@pyqtProperty(InstanceContainer, fset = setIntent, notify = pyqtContainersChanged)
def intent(self) -> InstanceContainer:
"""Get the quality container.
:return: The intent container. Should always be a valid container, but can be equal to the empty InstanceContainer.
"""
@ -116,7 +116,7 @@ class CuraContainerStack(ContainerStack):
def setQuality(self, new_quality: InstanceContainer, postpone_emit: bool = False) -> None:
"""Set the quality container.
:param new_quality: The new quality container. It is expected to have a "type" metadata entry with the value "quality".
"""
@ -125,7 +125,7 @@ class CuraContainerStack(ContainerStack):
@pyqtProperty(InstanceContainer, fset = setQuality, notify = pyqtContainersChanged)
def quality(self) -> InstanceContainer:
"""Get the quality container.
:return: The quality container. Should always be a valid container, but can be equal to the empty InstanceContainer.
"""
@ -133,7 +133,7 @@ class CuraContainerStack(ContainerStack):
def setMaterial(self, new_material: InstanceContainer, postpone_emit: bool = False) -> None:
"""Set the material container.
:param new_material: The new material container. It is expected to have a "type" metadata entry with the value "material".
"""
@ -142,7 +142,7 @@ class CuraContainerStack(ContainerStack):
@pyqtProperty(InstanceContainer, fset = setMaterial, notify = pyqtContainersChanged)
def material(self) -> InstanceContainer:
"""Get the material container.
:return: The material container. Should always be a valid container, but can be equal to the empty InstanceContainer.
"""
@ -150,7 +150,7 @@ class CuraContainerStack(ContainerStack):
def setVariant(self, new_variant: InstanceContainer) -> None:
"""Set the variant container.
:param new_variant: The new variant container. It is expected to have a "type" metadata entry with the value "variant".
"""
@ -159,7 +159,7 @@ class CuraContainerStack(ContainerStack):
@pyqtProperty(InstanceContainer, fset = setVariant, notify = pyqtContainersChanged)
def variant(self) -> InstanceContainer:
"""Get the variant container.
:return: The variant container. Should always be a valid container, but can be equal to the empty InstanceContainer.
"""
@ -167,7 +167,7 @@ class CuraContainerStack(ContainerStack):
def setDefinitionChanges(self, new_definition_changes: InstanceContainer) -> None:
"""Set the definition changes container.
:param new_definition_changes: The new definition changes container. It is expected to have a "type" metadata entry with the value "definition_changes".
"""
@ -176,7 +176,7 @@ class CuraContainerStack(ContainerStack):
@pyqtProperty(InstanceContainer, fset = setDefinitionChanges, notify = pyqtContainersChanged)
def definitionChanges(self) -> InstanceContainer:
"""Get the definition changes container.
:return: The definition changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
"""
@ -184,7 +184,7 @@ class CuraContainerStack(ContainerStack):
def setDefinition(self, new_definition: DefinitionContainerInterface) -> None:
"""Set the definition container.
:param new_definition: The new definition container. It is expected to have a "type" metadata entry with the value "definition".
"""
@ -206,10 +206,10 @@ class CuraContainerStack(ContainerStack):
@pyqtSlot(str, result = bool)
def hasUserValue(self, key: str) -> bool:
"""Check whether the specified setting has a 'user' value.
A user value here is defined as the setting having a value in either
the UserChanges or QualityChanges container.
:return: True if the setting has a user value, False if not.
"""
@ -223,11 +223,11 @@ class CuraContainerStack(ContainerStack):
def setProperty(self, key: str, property_name: str, property_value: Any, container: "ContainerInterface" = None, set_from_cache: bool = False) -> None:
"""Set a property of a setting.
This will set a property of a specified setting. Since the container stack does not contain
any settings itself, it is required to specify a container to set the property on. The target
container is matched by container type.
:param key: The key of the setting to set.
:param property_name: The name of the property to set.
:param new_value: The new value to set the property to.
@ -239,7 +239,7 @@ class CuraContainerStack(ContainerStack):
@override(ContainerStack)
def addContainer(self, container: ContainerInterface) -> None:
"""Overridden from ContainerStack
Since we have a fixed order of containers in the stack and this method would modify the container
ordering, we disallow this operation.
"""
@ -249,7 +249,7 @@ class CuraContainerStack(ContainerStack):
@override(ContainerStack)
def insertContainer(self, index: int, container: ContainerInterface) -> None:
"""Overridden from ContainerStack
Since we have a fixed order of containers in the stack and this method would modify the container
ordering, we disallow this operation.
"""
@ -259,7 +259,7 @@ class CuraContainerStack(ContainerStack):
@override(ContainerStack)
def removeContainer(self, index: int = 0) -> None:
"""Overridden from ContainerStack
Since we have a fixed order of containers in the stack and this method would modify the container
ordering, we disallow this operation.
"""
@ -269,10 +269,10 @@ class CuraContainerStack(ContainerStack):
@override(ContainerStack)
def replaceContainer(self, index: int, container: ContainerInterface, postpone_emit: bool = False) -> None:
"""Overridden from ContainerStack
Replaces the container at the specified index with another container.
This version performs checks to make sure the new container has the expected metadata and type.
:throws Exception.InvalidContainerError Raised when trying to replace a container with a container that has an incorrect type.
"""
@ -292,12 +292,12 @@ class CuraContainerStack(ContainerStack):
@override(ContainerStack)
def deserialize(self, serialized: str, file_name: Optional[str] = None) -> str:
"""Overridden from ContainerStack
This deserialize will make sure the internal list of containers matches with what we expect.
It will first check to see if the container at a certain index already matches with what we
expect. If it does not, it will search for a matching container with the correct type. Should
no container with the correct type be found, it will use the empty container.
:raise InvalidContainerStackError: Raised when no definition can be found for the stack.
"""
@ -357,12 +357,12 @@ class CuraContainerStack(ContainerStack):
@classmethod
def _findInstanceContainerDefinitionId(cls, machine_definition: DefinitionContainerInterface) -> str:
"""Find the ID that should be used when searching for instance containers for a specified definition.
This handles the situation where the definition specifies we should use a different definition when
searching for instance containers.
:param machine_definition: The definition to find the "quality definition" for.
:return: The ID of the definition container to use when searching for instance containers.
"""

View file

@ -20,10 +20,10 @@ class CuraStackBuilder:
@classmethod
def createMachine(cls, name: str, definition_id: str) -> Optional[GlobalStack]:
"""Create a new instance of a machine.
:param name: The name of the new machine.
:param definition_id: The ID of the machine definition to use.
:return: The new global stack or None if an error occurred.
"""
@ -77,7 +77,7 @@ class CuraStackBuilder:
@classmethod
def createExtruderStackWithDefaultSetup(cls, global_stack: "GlobalStack", extruder_position: int) -> None:
"""Create a default Extruder Stack
:param global_stack: The global stack this extruder refers to.
:param extruder_position: The position of the current extruder.
"""
@ -134,7 +134,7 @@ class CuraStackBuilder:
quality_container: "InstanceContainer") -> ExtruderStack:
"""Create a new Extruder stack
:param new_stack_id: The ID of the new stack.
:param extruder_definition: The definition to base the new stack on.
:param machine_definition_id: The ID of the machine definition to use for the user container.
@ -142,7 +142,7 @@ class CuraStackBuilder:
:param variant_container: The variant selected for the current extruder.
:param material_container: The material selected for the current extruder.
:param quality_container: The quality selected for the current extruder.
:return: A new Extruder stack instance with the specified parameters.
"""
@ -181,13 +181,13 @@ class CuraStackBuilder:
quality_container: "InstanceContainer") -> GlobalStack:
"""Create a new Global stack
:param new_stack_id: The ID of the new stack.
:param definition: The definition to base the new stack on.
:param variant_container: The variant selected for the current stack.
:param material_container: The material selected for the current stack.
:param quality_container: The quality selected for the current stack.
:return: A new Global stack instance with the specified parameters.
"""

View file

@ -37,7 +37,7 @@ class ExtruderStack(CuraContainerStack):
@override(ContainerStack)
def setNextStack(self, stack: CuraContainerStack, connect_signals: bool = True) -> None:
"""Overridden from ContainerStack
This will set the next stack and ensure that we register this stack as an extruder.
"""
@ -71,7 +71,7 @@ class ExtruderStack(CuraContainerStack):
def getCompatibleMaterialDiameter(self) -> float:
"""Return the filament diameter that the machine requires.
If the machine has no requirement for the diameter, -1 is returned.
:return: The filament diameter for the printer
"""
@ -99,12 +99,12 @@ class ExtruderStack(CuraContainerStack):
def getApproximateMaterialDiameter(self) -> float:
"""Return the approximate filament diameter that the machine requires.
The approximate material diameter is the material diameter rounded to
the nearest millimetre.
If the machine has no requirement for the diameter, -1 is returned.
:return: The approximate filament diameter for the printer
"""
@ -116,12 +116,12 @@ class ExtruderStack(CuraContainerStack):
@override(ContainerStack)
def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any:
"""Overridden from ContainerStack
It will perform a few extra checks when trying to get properties.
The two extra checks it currently does is to ensure a next stack is set and to bypass
the extruder when the property is not settable per extruder.
:throws Exceptions.NoGlobalStackError Raised when trying to get a property from an extruder without
having a next stack set.
"""

View file

@ -62,7 +62,7 @@ class GlobalStack(CuraContainerStack):
@deprecated("Please use extruderList instead.", "4.4")
def extruders(self) -> Dict[str, "ExtruderStack"]:
"""Get the list of extruders of this stack.
:return: The extruders registered with this stack.
"""
@ -91,11 +91,11 @@ class GlobalStack(CuraContainerStack):
@pyqtProperty("QVariantList", notify=configuredConnectionTypesChanged)
def configuredConnectionTypes(self) -> List[int]:
"""The configured connection types can be used to find out if the global
stack is configured to be connected with a printer, without having to
know all the details as to how this is exactly done (and without
actually setting the stack to be active).
This data can then in turn also be used when the global stack is active;
If we can't get a network connection, but it is configured to have one,
we can display a different icon to indicate the difference.
@ -171,9 +171,9 @@ class GlobalStack(CuraContainerStack):
def addExtruder(self, extruder: ContainerStack) -> None:
"""Add an extruder to the list of extruders of this stack.
:param extruder: The extruder to add.
:raise Exceptions.TooManyExtrudersError: Raised when trying to add an extruder while we
already have the maximum number of extruders.
"""
@ -194,15 +194,15 @@ class GlobalStack(CuraContainerStack):
@override(ContainerStack)
def getProperty(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> Any:
"""Overridden from ContainerStack
This will return the value of the specified property for the specified setting,
unless the property is "value" and that setting has a "resolve" function set.
When a resolve is set, it will instead try and execute the resolve first and
then fall back to the normal "value" property.
:param key: The setting key to get the property of.
:param property_name: The property to get the value of.
:return: The value of the property for the specified setting, or None if not found.
"""
@ -248,7 +248,7 @@ class GlobalStack(CuraContainerStack):
@override(ContainerStack)
def setNextStack(self, stack: CuraContainerStack, connect_signals: bool = True) -> None:
"""Overridden from ContainerStack
This will simply raise an exception since the Global stack cannot have a next stack.
"""
@ -281,7 +281,7 @@ class GlobalStack(CuraContainerStack):
def isValid(self) -> bool:
"""Perform some sanity checks on the global stack
Sanity check for extruders; they must have positions 0 and up to machine_extruder_count - 1
"""
container_registry = ContainerRegistry.getInstance()

View file

@ -32,9 +32,9 @@ class IntentManager(QObject):
def intentMetadatas(self, definition_id: str, nozzle_name: str, material_base_file: str) -> List[Dict[str, Any]]:
"""Gets the metadata dictionaries of all intent profiles for a given
configuration.
:param definition_id: ID of the printer.
:param nozzle_name: Name of the nozzle.
:param material_base_file: The base_file of the material.
@ -58,9 +58,9 @@ class IntentManager(QObject):
def intentCategories(self, definition_id: str, nozzle_id: str, material_id: str) -> List[str]:
"""Collects and returns all intent categories available for the given
parameters. Note that the 'default' category is always available.
:param definition_id: ID of the printer.
:param nozzle_name: Name of the nozzle.
:param material_id: ID of the material.
@ -74,10 +74,10 @@ class IntentManager(QObject):
def getCurrentAvailableIntents(self) -> List[Tuple[str, str]]:
"""List of intents to be displayed in the interface.
For the interface this will have to be broken up into the different
intent categories. That is up to the model there.
:return: A list of tuples of intent_category and quality_type. The actual
instance may vary per extruder.
"""
@ -109,7 +109,7 @@ class IntentManager(QObject):
def currentAvailableIntentCategories(self) -> List[str]:
"""List of intent categories available in either of the extruders.
This is purposefully inconsistent with the way that the quality types
are listed. The quality types will show all quality types available in
the printer using any configuration. This will only list the intent
@ -134,7 +134,7 @@ class IntentManager(QObject):
def getDefaultIntent(self) -> "InstanceContainer":
"""The intent that gets selected by default when no intent is available for
the configuration, an extruder can't match the intent that the user
selects, or just when creating a new printer.
"""

View file

@ -342,7 +342,7 @@ class MachineManager(QObject):
@staticmethod
def getMachine(definition_id: str, metadata_filter: Optional[Dict[str, str]] = None) -> Optional["GlobalStack"]:
"""Given a definition id, return the machine with this id.
Optional: add a list of keys and values to filter the list of machines with the given definition id
:param definition_id: :type{str} definition id that needs to look for
:param metadata_filter: :type{dict} list of metadata keys and values used for filtering
@ -430,7 +430,7 @@ class MachineManager(QObject):
@pyqtSlot(str)
def clearUserSettingAllCurrentStacks(self, key: str) -> None:
"""Delete a user setting from the global stack and all extruder stacks.
:param key: :type{str} the name of the key to delete
"""
Logger.log("i", "Clearing the setting [%s] from all stacks", key)
@ -464,7 +464,7 @@ class MachineManager(QObject):
@pyqtProperty(bool, notify = stacksValidationChanged)
def stacksHaveErrors(self) -> bool:
"""Check if none of the stacks contain error states
Note that the _stacks_have_errors is cached due to performance issues
Calling _checkStack(s)ForErrors on every change is simply too expensive
"""
@ -503,7 +503,7 @@ class MachineManager(QObject):
@pyqtProperty(bool, notify = printerConnectedStatusChanged)
def activeMachineHasCloudRegistration(self) -> bool:
return self.activeMachine is not None and ConnectionType.CloudConnection in self.activeMachine.configuredConnectionTypes
@pyqtProperty(bool, notify = printerConnectedStatusChanged)
def activeMachineIsUsingCloudConnection(self) -> bool:
return self.activeMachineHasCloudConnection and not self.activeMachineHasNetworkConnection
@ -544,9 +544,9 @@ class MachineManager(QObject):
@pyqtProperty(float, notify = activeQualityGroupChanged)
def activeQualityLayerHeight(self) -> float:
"""Gets the layer height of the currently active quality profile.
This is indicated together with the name of the active quality profile.
:return: The layer height of the currently active quality profile. If
there is no quality profile, this returns the default layer height.
"""
@ -623,7 +623,7 @@ class MachineManager(QObject):
@pyqtProperty(bool, notify = activeQualityChanged)
def isCurrentSetupSupported(self) -> bool:
"""Returns whether there is anything unsupported in the current set-up.
The current set-up signifies the global stack and all extruder stacks,
so this indicates whether there is any container in any of the container
stacks that is not marked as supported.
@ -670,7 +670,7 @@ class MachineManager(QObject):
@pyqtProperty(str, notify = globalContainerChanged)
def activeQualityDefinitionId(self) -> str:
"""Get the Definition ID to use to select quality profiles for the currently active machine
:returns: DefinitionID (string) if found, empty string otherwise
"""
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
@ -681,7 +681,7 @@ class MachineManager(QObject):
@pyqtProperty(str, notify = globalContainerChanged)
def activeDefinitionVariantsName(self) -> str:
"""Gets how the active definition calls variants
Caveat: per-definition-variant-title is currently not translated (though the fallback is)
"""
fallback_title = catalog.i18nc("@label", "Nozzle")
@ -754,7 +754,7 @@ class MachineManager(QObject):
@pyqtProperty(bool, notify = activeMaterialChanged)
def variantBuildplateUsable(self) -> bool:
"""The selected buildplate is usable if it is usable for all materials OR it is compatible for one but not compatible
for the other material but the buildplate is still usable
"""
if not self._global_container_stack:
@ -780,7 +780,7 @@ class MachineManager(QObject):
@pyqtSlot(str, result = str)
def getDefinitionByMachineId(self, machine_id: str) -> Optional[str]:
"""Get the Definition ID of a machine (specified by ID)
:param machine_id: string machine id to get the definition ID of
:returns: DefinitionID if found, None otherwise
"""
@ -834,7 +834,7 @@ class MachineManager(QObject):
def setActiveMachineExtruderCount(self, extruder_count: int) -> None:
"""Set the amount of extruders on the active machine (global stack)
:param extruder_count: int the number of extruders to set
"""
if self._global_container_stack is None:
@ -979,7 +979,7 @@ class MachineManager(QObject):
def _getContainerChangedSignals(self) -> List[Signal]:
"""Get the signals that signal that the containers changed for all stacks.
This includes the global stack and all extruder stacks. So if any
container changed anywhere.
"""
@ -999,7 +999,7 @@ class MachineManager(QObject):
@pyqtSlot(str)
def resetSettingForAllExtruders(self, setting_name: str) -> None:
"""Reset all setting properties of a setting for all extruders.
:param setting_name: The ID of the setting to reset.
"""
if self._global_container_stack is None:
@ -1247,7 +1247,7 @@ class MachineManager(QObject):
@pyqtSlot()
def updateMaterialWithVariant(self, position: Optional[str] = None) -> None:
"""Update the material profile in the current stacks when the variant is
changed.
:param position: The extruder stack to update. If provided with None, all
extruder stacks will be updated.
@ -1289,7 +1289,7 @@ class MachineManager(QObject):
@pyqtSlot(str)
def switchPrinterType(self, machine_name: str) -> None:
"""Given a printer definition name, select the right machine instance. In case it doesn't exist, create a new
instance with the same network key.
"""
# Don't switch if the user tries to change to the same type of printer
@ -1311,7 +1311,7 @@ class MachineManager(QObject):
if not new_machine:
Logger.log("e", "Failed to create new machine when switching configuration.")
return
for metadata_key in self._global_container_stack.getMetaData():
if metadata_key in new_machine.getMetaData():
continue # Don't copy the already preset stuff.
@ -1444,7 +1444,7 @@ class MachineManager(QObject):
@pyqtSlot(str, "QVariant")
def setMaterial(self, position: str, container_node, global_stack: Optional["GlobalStack"] = None) -> None:
"""Global_stack: if you want to provide your own global_stack instead of the current active one
if you update an active machine, special measures have to be taken.
"""
if global_stack is not None and global_stack != self._global_container_stack:
@ -1495,7 +1495,7 @@ class MachineManager(QObject):
@pyqtSlot(QObject)
def setQualityGroup(self, quality_group: "QualityGroup", no_dialog: bool = False, global_stack: Optional["GlobalStack"] = None) -> None:
"""Optionally provide global_stack if you want to use your own
The active global_stack is treated differently.
"""
if global_stack is not None and global_stack != self._global_container_stack:
@ -1562,7 +1562,7 @@ class MachineManager(QObject):
@pyqtSlot(str)
def setIntentByCategory(self, intent_category: str) -> None:
"""Change the intent category of the current printer.
All extruders can change their profiles. If an intent profile is
available with the desired intent category, that one will get chosen.
Otherwise the intent profile will be left to the empty profile, which
@ -1603,7 +1603,7 @@ class MachineManager(QObject):
def activeQualityGroup(self) -> Optional["QualityGroup"]:
"""Get the currently activated quality group.
If no printer is added yet or the printer doesn't have quality profiles,
this returns ``None``.
:return: The currently active quality group.
@ -1617,7 +1617,7 @@ class MachineManager(QObject):
@pyqtProperty(str, notify = activeQualityGroupChanged)
def activeQualityGroupName(self) -> str:
"""Get the name of the active quality group.
:return: The name of the active quality group.
"""
quality_group = self.activeQualityGroup()

View file

@ -13,7 +13,7 @@ from UM.Settings.InstanceContainer import InstanceContainer
class MachineNameValidator(QObject):
"""Are machine names valid?
Performs checks based on the length of the name.
"""
@ -37,7 +37,7 @@ class MachineNameValidator(QObject):
def validate(self, name):
"""Check if a specified machine name is allowed.
:param name: The machine name to check.
:return: ``QValidator.Invalid`` if it's disallowed, or ``QValidator.Acceptable`` if it's allowed.
"""

View file

@ -18,7 +18,7 @@ from cura.Settings.ExtruderManager import ExtruderManager
@signalemitter
class SettingOverrideDecorator(SceneNodeDecorator):
"""A decorator that adds a container stack to a Node. This stack should be queried for all settings regarding
the linked node. The Stack in question will refer to the global stack (so that settings that are not defined by
this stack still resolve.
"""
@ -27,7 +27,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
_non_printing_mesh_settings = {"anti_overhang_mesh", "infill_mesh", "cutting_mesh"}
"""Non-printing meshes
If these settings are True for any mesh, the mesh does not need a convex hull,
and is sent to the slicer regardless of whether it fits inside the build volume.
Note that Support Mesh is not in here because it actually generates
@ -83,7 +83,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def getActiveExtruder(self):
"""Gets the currently active extruder to print this object with.
:return: An extruder's container stack.
"""
@ -91,7 +91,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def getActiveExtruderChangedSignal(self):
"""Gets the signal that emits if the active extruder changed.
This can then be accessed via a decorator.
"""
@ -99,7 +99,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def getActiveExtruderPosition(self):
"""Gets the currently active extruders position
:return: An extruder's position, or None if no position info is available.
"""
@ -137,7 +137,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def _updateNextStack(self):
"""Makes sure that the stack upon which the container stack is placed is
kept up to date.
"""
if self._extruder_stack:
@ -160,7 +160,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def setActiveExtruder(self, extruder_stack_id):
"""Changes the extruder with which to print this node.
:param extruder_stack_id: The new extruder stack to print with.
"""

View file

@ -75,7 +75,7 @@ class MachineActionManager(QObject):
def addRequiredAction(self, definition_id: str, action_key: str) -> None:
"""Add a required action to a machine
Raises an exception when the action is not recognised.
"""
if action_key in self._machine_actions:
@ -112,7 +112,7 @@ class MachineActionManager(QObject):
def addMachineAction(self, action: "MachineAction") -> None:
"""Add a (unique) MachineAction
if the Key of the action is not unique, an exception is raised.
"""
if action.getKey() not in self._machine_actions:
@ -123,7 +123,7 @@ class MachineActionManager(QObject):
@pyqtSlot(str, result = "QVariantList")
def getSupportedActions(self, definition_id: str) -> List["MachineAction"]:
"""Get all actions supported by given machine
:param definition_id: The ID of the definition you want the supported actions of
:returns: set of supported actions.
"""
@ -134,7 +134,7 @@ class MachineActionManager(QObject):
def getRequiredActions(self, definition_id: str) -> List["MachineAction"]:
"""Get all actions required by given machine
:param definition_id: The ID of the definition you want the required actions of
:returns: set of required actions.
"""
@ -146,7 +146,7 @@ class MachineActionManager(QObject):
@pyqtSlot(str, result = "QVariantList")
def getFirstStartActions(self, definition_id: str) -> List["MachineAction"]:
"""Get all actions that need to be performed upon first start of a given machine.
Note that contrary to required / supported actions a list is returned (as it could be required to run the same
action multiple times).
:param definition_id: The ID of the definition that you want to get the "on added" actions for.
@ -159,7 +159,7 @@ class MachineActionManager(QObject):
def removeMachineAction(self, action: "MachineAction") -> None:
"""Remove Machine action from manager
:param action: to remove
"""
try:
@ -169,7 +169,7 @@ class MachineActionManager(QObject):
def getMachineAction(self, key: str) -> Optional["MachineAction"]:
"""Get MachineAction by key
:param key: String of key to select
:return: Machine action if found, None otherwise
"""

View file

@ -23,7 +23,7 @@ catalog = i18nCatalog("cura")
class PrintInformation(QObject):
"""A class for processing and the print times per build plate as well as managing the job name
This class also mangles the current machine name and the filename of the first loaded mesh into a job name.
This job name is requested by the JobSpecs qml file.
"""

View file

@ -13,9 +13,9 @@ SEMANTIC_VERSION_REGEX = re.compile(r"^[0-9]+\.[0-9]+(\.[0-9]+)?$")
def api(since_version: str) -> Callable:
"""Decorator for functions that belong to a set of APIs. For now, this should only be used for officially supported
APIs, meaning that those APIs should be versioned and maintained.
:param since_version: The earliest version since when this API becomes supported. This means that since this version,
this API function is supposed to behave the same. This parameter is not used. It's just a
documentation.

View file

@ -59,11 +59,11 @@ class ThreeMFReader(MeshReader):
temp_mat = Matrix()
"""Transformation is saved as:
M00 M01 M02 0.0
M10 M11 M12 0.0
M20 M21 M22 0.0
M30 M31 M32 1.0
We switch the row & cols as that is how everyone else uses matrices!
"""
@ -87,7 +87,7 @@ class ThreeMFReader(MeshReader):
def _convertSavitarNodeToUMNode(self, savitar_node: Savitar.SceneNode, file_name: str = "") -> Optional[SceneNode]:
"""Convenience function that converts a SceneNode object (as obtained from libSavitar) to a scene node.
:returns: Scene node.
"""
try:
@ -252,7 +252,7 @@ class ThreeMFReader(MeshReader):
def _getScaleFromUnit(self, unit: Optional[str]) -> Vector:
"""Create a scale vector based on a unit string.
.. The core spec defines the following:
* micron
* millimeter (default)

View file

@ -133,7 +133,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
def getNewId(self, old_id: str):
"""Get a unique name based on the old_id. This is different from directly calling the registry in that it caches results.
This has nothing to do with speed, but with getting consistent new naming for instances & objects.
"""
if old_id not in self._id_mapping:
@ -142,7 +142,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
def _determineGlobalAndExtruderStackFiles(self, project_file_name: str, file_list: List[str]) -> Tuple[str, List[str]]:
"""Separates the given file list into a list of GlobalStack files and a list of ExtruderStack files.
In old versions, extruder stack files have the same suffix as container stack files ".stack.cfg".
"""
@ -187,7 +187,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
def preRead(self, file_name, show_dialog=True, *args, **kwargs):
"""Read some info so we can make decisions
:param file_name:
:param show_dialog: In case we use preRead() to check if a file is a valid project file,
we don't want to show a dialog.
@ -588,12 +588,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
@call_on_qt_thread
def read(self, file_name):
"""Read the project file
Add all the definitions / materials / quality changes that do not exist yet. Then it loads
all the stacks into the container registry. In some cases it will reuse the container for the global stack.
It handles old style project files containing .stack.cfg as well as new style project files
containing global.cfg / extruder.cfg
:param file_name:
"""
application = CuraApplication.getInstance()
@ -879,7 +879,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
def _createNewQualityChanges(self, quality_type: str, intent_category: Optional[str], name: str, global_stack: GlobalStack, extruder_stack: Optional[ExtruderStack]) -> InstanceContainer:
"""Helper class to create a new quality changes profile.
This will then later be filled with the appropriate data.
:param quality_type: The quality type of the new profile.

View file

@ -33,7 +33,7 @@ def getMetaData() -> Dict:
"description": catalog.i18nc("@item:inlistbox", "3MF File")
}
]
return metaData

View file

@ -110,7 +110,7 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
@staticmethod
def _writeContainerToArchive(container, archive):
"""Helper function that writes ContainerStacks, InstanceContainers and DefinitionContainers to the archive.
:param container: That follows the :type{ContainerInterface} to archive.
:param archive: The archive to write to.
"""

View file

@ -62,7 +62,7 @@ class ThreeMFWriter(MeshWriter):
def setStoreArchive(self, store_archive):
"""Should we store the archive
Note that if this is true, the archive will not be closed.
The object that set this parameter is then responsible for closing it correctly!
"""
@ -70,7 +70,7 @@ class ThreeMFWriter(MeshWriter):
def _convertUMNodeToSavitarNode(self, um_node, transformation = Matrix()):
"""Convenience function that converts an Uranium SceneNode object to a SavitarSceneNode
:returns: Uranium Scene node.
"""
if not isinstance(um_node, SceneNode):

View file

@ -149,7 +149,7 @@ class AMFReader(MeshReader):
def _toMeshData(self, tri_node: trimesh.base.Trimesh, file_name: str = "") -> MeshData:
"""Converts a Trimesh to Uranium's MeshData.
:param tri_node: A Trimesh containing the contents of a file that was just read.
:param file_name: The full original filename used to watch for changes
:return: Mesh data from the Trimesh in a way that Uranium can understand it.

View file

@ -207,7 +207,7 @@ class CuraEngineBackend(QObject, Backend):
printDurationMessage = Signal()
"""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.

View file

@ -30,7 +30,7 @@ catalog = i18nCatalog("cura")
def colorCodeToRGBA(color_code):
"""Return a 4-tuple with floats 0-1 representing the html color code
:param color_code: html color code, i.e. "#FF0000" -> red
"""
@ -55,7 +55,7 @@ class ProcessSlicedLayersJob(Job):
def abort(self):
"""Aborts the processing of layers.
This abort is made on a best-effort basis, meaning that the actual
job thread will check once in a while to see whether an abort is
requested and then stop processing by itself. There is no guarantee

View file

@ -16,21 +16,21 @@ import zipfile
class CuraProfileReader(ProfileReader):
"""A plugin that reads profile data from Cura profile files.
It reads a profile from a .curaprofile file, and returns it as a profile
instance.
"""
def __init__(self) -> None:
"""Initialises the cura profile reader.
This does nothing since the only other function is basically stateless.
"""
super().__init__()
def read(self, file_name: str) -> List[Optional[InstanceContainer]]:
"""Reads a cura profile from a file and returns it.
:param file_name: The file to read the cura profile from.
:return: The cura profiles that were in the file, if any. If the file
could not be read or didn't contain a valid profile, ``None`` is
@ -59,7 +59,7 @@ class CuraProfileReader(ProfileReader):
def _upgradeProfile(self, serialized: str, profile_id: str) -> List[Tuple[str, str]]:
"""Convert a profile from an old Cura to this Cura if needed.
:param serialized: The profile data to convert in the serialized on-disk format.
:param profile_id: The name of the profile.
:return: List of serialized profile strings and matching profile names.
@ -85,7 +85,7 @@ class CuraProfileReader(ProfileReader):
def _loadProfile(self, serialized: str, profile_id: str) -> Optional[InstanceContainer]:
"""Load a profile from a serialized string.
:param serialized: The profile data to read.
:param profile_id: The name of the profile.
:return: The profile that was stored in the string.
@ -114,7 +114,7 @@ class CuraProfileReader(ProfileReader):
def _upgradeProfileVersion(self, serialized: str, profile_id: str, main_version: int, setting_version: int) -> List[Tuple[str, str]]:
"""Upgrade a serialized profile to the current profile format.
:param serialized: The profile data to convert.
:param profile_id: The name of the profile.
:param source_version: The profile version of 'serialized'.

View file

@ -11,7 +11,7 @@ class CuraProfileWriter(ProfileWriter):
def write(self, path, profiles):
"""Writes a profile to the specified file path.
:param path: :type{string} The file to output to.
:param profiles: :type{Profile} :type{List} The profile(s) to write to that file.
:return: True if the writing was successful, or

View file

@ -20,7 +20,7 @@ i18n_catalog = i18nCatalog("cura")
class FirmwareUpdateChecker(Extension):
"""This Extension checks for new versions of the firmware based on the latest checked version number.
The plugin is currently only usable for applications maintained by Ultimaker. But it should be relatively easy
to change it to work for other applications.
"""
@ -62,10 +62,10 @@ class FirmwareUpdateChecker(Extension):
def checkFirmwareVersion(self, container = None, silent = False):
"""Connect with software.ultimaker.com, load latest.version and check version info.
If the version info is different from the current version, spawn a message to
allow the user to download it.
:param silent: type(boolean) Suppresses messages other than "new version found" messages.
This is used when checking for a new firmware version at startup.
"""

View file

@ -10,7 +10,7 @@ from UM.PluginRegistry import PluginRegistry
class GCodeGzReader(MeshReader):
"""A file reader that reads gzipped g-code.
If you're zipping g-code, you might as well use gzip!
"""

View file

@ -16,7 +16,7 @@ catalog = i18nCatalog("cura")
class GCodeGzWriter(MeshWriter):
"""A file writer that writes gzipped g-code.
If you're zipping g-code, you might as well use gzip!
"""
@ -26,11 +26,11 @@ class GCodeGzWriter(MeshWriter):
def write(self, stream: BufferedIOBase, nodes: List[SceneNode], mode = MeshWriter.OutputMode.BinaryMode) -> bool:
"""Writes the gzipped g-code to a stream.
Note that even though the function accepts a collection of nodes, the
entire scene is always written to the file since it is not possible to
separate the g-code for just specific nodes.
:param stream: The stream to write the gzipped g-code to.
:param nodes: This is ignored.
:param mode: Additional information on what type of stream to use. This

View file

@ -15,14 +15,14 @@ from cura.ReaderWriters.ProfileReader import ProfileReader, NoProfileException
class GCodeProfileReader(ProfileReader):
"""A class that reads profile data from g-code files.
It reads the profile data from g-code files and stores it in a new profile.
This class currently does not process the rest of the g-code in any way.
"""
version = 3
"""The file format version of the serialized g-code.
It can only read settings with the same version as the version it was
written with. If the file format is changed in a way that breaks reverse
compatibility, increment this version number!
@ -48,7 +48,7 @@ class GCodeProfileReader(ProfileReader):
def read(self, file_name):
"""Reads a g-code file, loading the profile from it.
:param file_name: The name of the file to read the profile from.
:return: The profile that was in the specified file, if any. If the
specified file was no g-code or contained no parsable profile,
@ -106,7 +106,7 @@ class GCodeProfileReader(ProfileReader):
def unescapeGcodeComment(string: str) -> str:
"""Unescape a string which has been escaped for use in a gcode comment.
:param string: The string to unescape.
:return: The unescaped string.
"""
@ -120,7 +120,7 @@ def unescapeGcodeComment(string: str) -> str:
def readQualityProfileFromString(profile_string) -> Optional[InstanceContainer]:
"""Read in a profile from a serialized string.
:param profile_string: The profile data in serialized form.
:return: The resulting Profile object or None if it could not be read.
"""

View file

@ -237,7 +237,7 @@ class FlavorParser:
def _gCode92(self, position: Position, params: PositionOptional, path: List[List[Union[float, int]]]) -> Position:
"""Reset the current position to the values specified.
For example: G92 X10 will set the X to 10 without any physical motion.
"""

View file

@ -21,7 +21,7 @@ class RepRapFlavorParser(FlavorParser.FlavorParser):
def _gCode90(self, position, params, path):
"""Set the absolute positioning
RepRapFlavor code G90 sets position of X, Y, Z to absolute
For absolute E, M82 is used
"""
@ -30,7 +30,7 @@ class RepRapFlavorParser(FlavorParser.FlavorParser):
def _gCode91(self, position, params, path):
"""Set the relative positioning
RepRapFlavor code G91 sets position of X, Y, Z to relative
For relative E, M83 is used
"""

View file

@ -17,12 +17,12 @@ catalog = i18nCatalog("cura")
class GCodeWriter(MeshWriter):
"""Writes g-code to a file.
While this poses as a mesh writer, what this really does is take the g-code
in the entire scene and write it to an output device. Since the g-code of a
single mesh isn't separable from the rest what with rafts and travel moves
and all, it doesn't make sense to write just a single mesh.
So this plug-in takes the g-code that is stored in the root of the scene
node tree, adds a bit of extra information about the profiles and writes
that to the output device.
@ -30,7 +30,7 @@ class GCodeWriter(MeshWriter):
version = 3
"""The file format version of the serialised g-code.
It can only read settings with the same version as the version it was
written with. If the file format is changed in a way that breaks reverse
compatibility, increment this version number!
@ -42,9 +42,9 @@ class GCodeWriter(MeshWriter):
re.escape("\r"): "\\r" # Carriage return. Windows users may need this for visualisation in their editors.
}
"""Dictionary that defines how characters are escaped when embedded in
g-code.
Note that the keys of this dictionary are regex strings. The values are
not.
"""
@ -58,11 +58,11 @@ class GCodeWriter(MeshWriter):
def write(self, stream, nodes, mode = MeshWriter.OutputMode.TextMode):
"""Writes the g-code for the entire scene to a stream.
Note that even though the function accepts a collection of nodes, the
entire scene is always written to the file since it is not possible to
separate the g-code for just specific nodes.
:param stream: The stream to write the g-code to.
:param nodes: This is ignored.
:param mode: Additional information on how to format the g-code in the
@ -117,10 +117,10 @@ class GCodeWriter(MeshWriter):
def _serialiseSettings(self, stack):
"""Serialises a container stack to prepare it for writing at the end of the g-code.
The settings are serialised, and special characters (including newline)
are escaped.
:param stack: A container stack to serialise.
:return: A serialised string of the settings.
"""

View file

@ -18,14 +18,14 @@ from cura.ReaderWriters.ProfileReader import ProfileReader # The plug-in type t
class LegacyProfileReader(ProfileReader):
"""A plugin that reads profile data from legacy Cura versions.
It reads a profile from an .ini file, and performs some translations on it.
Not all translations are correct, mind you, but it is a best effort.
"""
def __init__(self):
"""Initialises the legacy profile reader.
This does nothing since the only other function is basically stateless.
"""
@ -33,9 +33,9 @@ class LegacyProfileReader(ProfileReader):
def prepareDefaults(self, json: Dict[str, Dict[str, str]]) -> Dict[str, str]:
"""Prepares the default values of all legacy settings.
These are loaded from the Dictionary of Doom.
:param json: The JSON file to load the default setting values from. This
should not be a URL but a pre-loaded JSON handle.
:return: A dictionary of the default values of the legacy Cura version.
@ -49,13 +49,13 @@ class LegacyProfileReader(ProfileReader):
def prepareLocals(self, config_parser, config_section, defaults):
"""Prepares the local variables that can be used in evaluation of computing
new setting values from the old ones.
This fills a dictionary with all settings from the legacy Cura version
and their values, so that they can be used in evaluating the new setting
values as Python code.
:param config_parser: The ConfigParser that finds the settings in the
legacy profile.
:param config_section: The section in the profile where the settings
@ -71,7 +71,7 @@ class LegacyProfileReader(ProfileReader):
def read(self, file_name):
"""Reads a legacy Cura profile from a file and returns it.
:param file_name: The file to read the legacy Cura profile from.
:return: The legacy Cura profile that was in the file, if any. If the
file could not be read or didn't contain a valid profile, None is returned.

View file

@ -25,7 +25,7 @@ catalog = UM.i18n.i18nCatalog("cura")
class MachineSettingsAction(MachineAction):
"""This action allows for certain settings that are "machine only") to be modified.
It automatically detects machine definitions that it knows how to change and attaches itself to those.
"""
def __init__(self, parent: Optional["QObject"] = None) -> None:
@ -60,7 +60,7 @@ class MachineSettingsAction(MachineAction):
def _updateHasMaterialsInContainerTree(self) -> None:
"""Triggered when the global container stack changes or when the g-code
flavour setting is changed.
"""
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()

View file

@ -49,7 +49,7 @@ class ModelChecker(QObject, Extension):
def _pluginsInitialized(self):
"""Called when plug-ins are initialized.
This makes sure that we listen to changes of the material and that the
button is created that indicates warnings with the current set-up.
"""

View file

@ -17,7 +17,7 @@ from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
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):

View file

@ -14,7 +14,7 @@ from UM.Event import Event
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):
@ -52,7 +52,7 @@ class PerObjectSettingsTool(Tool):
def getSelectedActiveExtruder(self):
"""Gets the active extruder of the currently selected object.
:return: The active extruder of the currently selected object.
"""
@ -61,7 +61,7 @@ class PerObjectSettingsTool(Tool):
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.
"""

View file

@ -132,7 +132,7 @@ class PostProcessingPlugin(QObject, Extension):
def loadAllScripts(self) -> None:
"""Load all scripts from all paths where scripts can be found.
This should probably only be done on init.
"""
@ -157,7 +157,7 @@ class PostProcessingPlugin(QObject, Extension):
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.
"""
@ -360,7 +360,7 @@ class PostProcessingPlugin(QObject, Extension):
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

View file

@ -81,7 +81,7 @@ class Script:
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
@ -116,7 +116,7 @@ class Script:
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(';')):
@ -135,7 +135,7 @@ class Script:
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.
@ -190,7 +190,7 @@ class Script:
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()

View file

@ -20,7 +20,7 @@
# Uses -
# M163 - Set Mix Factor
# M164 - Save Mix - saves to T2 as a unique mix
import re #To perform the search and replace.
from ..Script import Script
@ -127,7 +127,7 @@ class ColorMix(Script):
firstMix = self.getSettingValueByKey("mix_start")
secondMix = self.getSettingValueByKey("mix_finish")
modelOfInterest = self.getSettingValueByKey("object_number")
#get layer height
layerHeight = 0
for active_layer in data:
@ -138,11 +138,11 @@ class ColorMix(Script):
break
if layerHeight != 0:
break
#default layerHeight if not found
if layerHeight == 0:
layerHeight = .2
#get layers to use
startLayer = 0
endLayer = 0

View file

@ -56,7 +56,7 @@ class DisplayFilenameAndLayerOnLCD(Script):
}
}
}"""
def execute(self, data):
max_layer = 0
if self.getSettingValueByKey("name") != "":
@ -96,5 +96,5 @@ class DisplayFilenameAndLayerOnLCD(Script):
i += 1
final_lines = "\n".join(lines)
data[layer_index] = final_lines
return data

View file

@ -65,7 +65,7 @@ class FilamentChange(Script):
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.
"""

View file

@ -8,7 +8,7 @@ from ..Script import Script
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.
"""

View file

@ -30,7 +30,7 @@ class UsePreviousProbeMeasurements(Script):
}
}
}"""
def execute(self, data):
text = "M501 ;load bed level data\nM420 S1 ;enable bed leveling"
if self.getSettingValueByKey("use_previous_measurements"):

View file

@ -14,7 +14,7 @@ if TYPE_CHECKING:
class PreviewStage(CuraStage):
"""Displays a preview of what you're about to print.
The Python component of this stage just loads PreviewMain.qml for display
when the stage is selected, and makes sure that it reverts to the previous
view when the previous stage is activated.
@ -28,14 +28,14 @@ class PreviewStage(CuraStage):
def onStageSelected(self) -> None:
"""When selecting the stage, remember which was the previous view so that
we can revert to that view when we go out of the stage later.
"""
self._previously_active_view = self._application.getController().getActiveView()
def onStageDeselected(self) -> None:
"""Called when going to a different stage (away from the Preview Stage).
When going to a different stage, the view should be reverted to what it
was before. Normally, that just reverts it to solid view.
"""
@ -46,7 +46,7 @@ class PreviewStage(CuraStage):
def _engineCreated(self) -> None:
"""Delayed load of the QML files.
We need to make sure that the QML engine is running before we can load
these.
"""

View file

@ -13,7 +13,7 @@ import subprocess
class LinuxRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
"""Support for removable devices on Linux.
TODO: This code uses the most basic interfaces for handling this.
We should instead use UDisks2 to handle mount/unmount and hotplugging events.
"""

View file

@ -30,7 +30,7 @@ class RemovableDriveOutputDevice(OutputDevice):
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
"""Request the specified nodes to be written to the removable drive.
:param nodes: A collection of scene nodes that should be written to the
removable drive.
:param file_name: :type{string} A suggestion for the file name to write to.
@ -38,7 +38,7 @@ class RemovableDriveOutputDevice(OutputDevice):
meshes.
:param limit_mimetypes: Should we limit the available MIME types to the
MIME types available to the currently active machine?
"""
filter_by_machine = True # This plugin is intended to be used by machine (regardless of what it was told to do)
@ -110,10 +110,10 @@ class RemovableDriveOutputDevice(OutputDevice):
def _automaticFileName(self, nodes):
"""Generate a file name automatically for the specified nodes to be saved in.
The name generated will be the name of one of the nodes. Which node that
is can not be guaranteed.
:param nodes: A collection of nodes for which to generate a file name.
"""
for root in nodes:

View file

@ -20,7 +20,7 @@ class SentryLogger(LogOutput):
# processed and ready for sending.
# Note that this only prepares them for sending. It only sends them when the user actually agrees to sending the
# information.
_levels = {
"w": "warning",
"i": "info",
@ -32,10 +32,10 @@ class SentryLogger(LogOutput):
def __init__(self) -> None:
super().__init__()
self._show_once = set() # type: Set[str]
def log(self, log_type: str, message: str) -> None:
"""Log the message to the sentry hub as a breadcrumb
:param log_type: "e" (error), "i"(info), "d"(debug), "w"(warning) or "c"(critical) (can postfix with "_once")
:param message: String containing message to be logged
"""

Some files were not shown because too many files have changed in this diff Show more