Browse Source

Merge branch 'master' into libArachne_rebased

Conflicts:
	resources/definitions/ultimaker2.def.json -> Additions in Arachne around a place where we fixed an enum setting.
	resources/definitions/ultimaker3.def.json
	resources/definitions/ultimaker_s3.def.json
	resources/definitions/ultimaker_s5.def.json
Ghostkeeper 3 years ago
parent
commit
b8ccb32836

+ 2 - 2
CITATION.cff

@@ -7,5 +7,5 @@ license: "LGPL-3.0"
 message: "If you use this software, please cite it using these metadata."
 repository-code: "https://github.com/ultimaker/cura/"
 title: "Ultimaker Cura"
-version: "4.10.0"
-...
+version: "4.12.0"
+...

+ 1 - 1
README.md

@@ -2,7 +2,7 @@ Cura
 ====
 Ultimaker Cura is a state-of-the-art slicer application to prepare your 3D models for printing with a 3D printer. With hundreds of settings and hundreds of community-managed print profiles, Ultimaker Cura is sure to lead your next project to a success.
 
-![Screenshot](screenshot.png)
+![Screenshot](cura-logo.PNG)
 
 Logging Issues
 ------------

BIN
cura-logo.PNG


+ 1 - 1
cura/API/Account.py

@@ -62,7 +62,7 @@ class Account(QObject):
     updatePackagesEnabledChanged = pyqtSignal(bool)
 
     CLIENT_SCOPES = "account.user.read drive.backup.read drive.backup.write packages.download " \
-                    "packages.rating.read packages.rating.write connect.cluster.read connect.cluster.write " \
+                    "packages.rating.read packages.rating.write connect.cluster.read connect.cluster.write connect.material.write " \
                     "library.project.read library.project.write cura.printjob.read cura.printjob.write " \
                     "cura.mesh.read cura.mesh.write"
 

+ 1 - 1
cura/Arranging/Nest2DArrange.py

@@ -159,4 +159,4 @@ def arrange(nodes_to_arrange: List["SceneNode"],
 
     grouped_operation, not_fit_count = createGroupOperationForArrange(nodes_to_arrange, build_volume, fixed_nodes, factor, add_new_nodes_in_scene)
     grouped_operation.push()
-    return not_fit_count != 0
+    return not_fit_count == 0

+ 7 - 2
cura/BuildVolume.py

@@ -6,6 +6,7 @@ import math
 
 from typing import List, Optional, TYPE_CHECKING, Any, Set, cast, Iterable, Dict
 
+from UM.Logger import Logger
 from UM.Mesh.MeshData import MeshData
 from UM.Mesh.MeshBuilder import MeshBuilder
 
@@ -289,7 +290,7 @@ class BuildVolume(SceneNode):
                 # Mark the node as outside build volume if the set extruder is disabled
                 extruder_position = node.callDecoration("getActiveExtruderPosition")
                 try:
-                    if not self._global_container_stack.extruderList[int(extruder_position)].isEnabled:
+                    if not self._global_container_stack.extruderList[int(extruder_position)].isEnabled and not node.callDecoration("isGroup"):
                         node.setOutsideBuildArea(True)
                         continue
                 except IndexError:  # Happens when the extruder list is too short. We're not done building the printer in memory yet.
@@ -1078,7 +1079,11 @@ class BuildVolume(SceneNode):
         # setting does *not* have a limit_to_extruder setting (which means that we can't ask the global extruder what
         # the value is.
         adhesion_extruder = self._global_container_stack.getProperty("adhesion_extruder_nr", "value")
-        adhesion_stack = self._global_container_stack.extruderList[int(adhesion_extruder)]
+        try:
+            adhesion_stack = self._global_container_stack.extruderList[int(adhesion_extruder)]
+        except IndexError:
+            Logger.warning(f"Couldn't find extruder with index '{adhesion_extruder}', defaulting to 0 instead.")
+            adhesion_stack = self._global_container_stack.extruderList[0]
         skirt_brim_line_width = adhesion_stack.getProperty("skirt_brim_line_width", "value")
 
         initial_layer_line_width_factor = adhesion_stack.getProperty("initial_layer_line_width_factor", "value")

+ 2 - 0
cura/CuraApplication.py

@@ -162,6 +162,7 @@ class CuraApplication(QtApplication):
         self.default_theme = "cura-light"
 
         self.change_log_url = "https://ultimaker.com/ultimaker-cura-latest-features?utm_source=cura&utm_medium=software&utm_campaign=cura-update-features"
+        self.beta_change_log_url = "https://ultimaker.com/ultimaker-cura-beta-features?utm_source=cura&utm_medium=software&utm_campaign=cura-update-features"
 
         self._boot_loading_time = time.time()
 
@@ -716,6 +717,7 @@ class CuraApplication(QtApplication):
             for extruder in global_stack.extruderList:
                 extruder.userChanges.clear()
             global_stack.userChanges.clear()
+            self.getMachineManager().correctExtruderSettings()
 
         # if the user decided to keep settings then the user settings should be re-calculated and validated for errors
         # before slicing. To ensure that slicer uses right settings values

+ 5 - 1
cura/Machines/Models/ExtrudersModel.py

@@ -59,6 +59,8 @@ class ExtrudersModel(ListModel):
     defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"]
     """List of colours to display if there is no material or the material has no known colour. """
 
+    MaterialNameRole = Qt.UserRole + 13
+
     def __init__(self, parent = None):
         """Initialises the extruders model, defining the roles and listening for changes in the data.
 
@@ -79,6 +81,7 @@ class ExtrudersModel(ListModel):
         self.addRoleName(self.MaterialBrandRole, "material_brand")
         self.addRoleName(self.ColorNameRole, "color_name")
         self.addRoleName(self.MaterialTypeRole, "material_type")
+        self.addRoleName(self.MaterialNameRole, "material_name")
         self._update_extruder_timer = QTimer()
         self._update_extruder_timer.setInterval(100)
         self._update_extruder_timer.setSingleShot(True)
@@ -199,8 +202,8 @@ class ExtrudersModel(ListModel):
                     "material_brand": material_brand,
                     "color_name": color_name,
                     "material_type": extruder.material.getMetaDataEntry("material") if extruder.material else "",
+                    "material_name": extruder.material.getMetaDataEntry("name") if extruder.material else "",
                 }
-
                 items.append(item)
                 extruders_changed = True
 
@@ -224,6 +227,7 @@ class ExtrudersModel(ListModel):
                     "material_brand": "",
                     "color_name": "",
                     "material_type": "",
+                    "material_label": ""
                 }
                 items.append(item)
             if self._items != items:

+ 45 - 3
cura/Machines/Models/GlobalStacksModel.py

@@ -1,7 +1,8 @@
-# Copyright (c) 2018 Ultimaker B.V.
+# Copyright (c) 2021 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
-from PyQt5.QtCore import Qt, QTimer
+from PyQt5.QtCore import Qt, QTimer, pyqtProperty, pyqtSignal
+from typing import Optional
 
 from UM.Qt.ListModel import ListModel
 from UM.i18n import i18nCatalog
@@ -20,6 +21,7 @@ class GlobalStacksModel(ListModel):
     MetaDataRole = Qt.UserRole + 5
     DiscoverySourceRole = Qt.UserRole + 6  # For separating local and remote printers in the machine management page
     RemovalWarningRole = Qt.UserRole + 7
+    IsOnlineRole = Qt.UserRole + 8
 
     def __init__(self, parent = None) -> None:
         super().__init__(parent)
@@ -31,18 +33,49 @@ class GlobalStacksModel(ListModel):
         self.addRoleName(self.HasRemoteConnectionRole, "hasRemoteConnection")
         self.addRoleName(self.MetaDataRole, "metadata")
         self.addRoleName(self.DiscoverySourceRole, "discoverySource")
+        self.addRoleName(self.IsOnlineRole, "isOnline")
 
         self._change_timer = QTimer()
         self._change_timer.setInterval(200)
         self._change_timer.setSingleShot(True)
         self._change_timer.timeout.connect(self._update)
 
+        self._filter_connection_type = None  # type: Optional[ConnectionType]
+        self._filter_online_only = False
+
         # Listen to changes
         CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerChanged)
         CuraContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerChanged)
         CuraContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged)
         self._updateDelayed()
 
+    filterConnectionTypeChanged = pyqtSignal()
+    def setFilterConnectionType(self, new_filter: Optional[ConnectionType]) -> None:
+        self._filter_connection_type = new_filter
+
+    @pyqtProperty(int, fset = setFilterConnectionType, notify = filterConnectionTypeChanged)
+    def filterConnectionType(self) -> int:
+        """
+        The connection type to filter the list of printers by.
+
+        Only printers that match this connection type will be listed in the
+        model.
+        """
+        if self._filter_connection_type is None:
+            return -1
+        return self._filter_connection_type.value
+
+    filterOnlineOnlyChanged = pyqtSignal()
+    def setFilterOnlineOnly(self, new_filter: bool) -> None:
+        self._filter_online_only = new_filter
+
+    @pyqtProperty(bool, fset = setFilterOnlineOnly, notify = filterOnlineOnlyChanged)
+    def filterOnlineOnly(self) -> bool:
+        """
+        Whether to filter the global stacks to show only printers that are online.
+        """
+        return self._filter_online_only
+
     def _onContainerChanged(self, container) -> None:
         """Handler for container added/removed events from registry"""
 
@@ -58,6 +91,10 @@ class GlobalStacksModel(ListModel):
 
         container_stacks = CuraContainerRegistry.getInstance().findContainerStacks(type = "machine")
         for container_stack in container_stacks:
+            if self._filter_connection_type is not None:  # We want to filter on connection types.
+                if not any((connection_type == self._filter_connection_type for connection_type in container_stack.configuredConnectionTypes)):
+                    continue  # No connection type on this printer matches the filter.
+
             has_remote_connection = False
 
             for connection_type in container_stack.configuredConnectionTypes:
@@ -67,6 +104,10 @@ class GlobalStacksModel(ListModel):
             if parseBool(container_stack.getMetaDataEntry("hidden", False)):
                 continue
 
+            is_online = container_stack.getMetaDataEntry("is_online", False)
+            if self._filter_online_only and not is_online:
+                continue
+
             device_name = container_stack.getMetaDataEntry("group_name", container_stack.getName())
             section_name = "Connected printers" if has_remote_connection else "Preset printers"
             section_name = self._catalog.i18nc("@info:title", section_name)
@@ -82,6 +123,7 @@ class GlobalStacksModel(ListModel):
                           "hasRemoteConnection": has_remote_connection,
                           "metadata": container_stack.getMetaData().copy(),
                           "discoverySource": section_name,
-                          "removalWarning": removal_warning})
+                          "removalWarning": removal_warning,
+                          "isOnline": is_online})
         items.sort(key=lambda i: (not i["hasRemoteConnection"], i["name"]))
         self.setItems(items)

+ 1 - 1
cura/Machines/Models/IntentCategoryModel.py

@@ -107,7 +107,7 @@ class IntentCategoryModel(ListModel):
             qualities = IntentModel()
             qualities.setIntentCategory(category)
             result.append({
-                "name": IntentCategoryModel.translation(category, "name", catalog.i18nc("@label", "Unknown")),
+                "name": IntentCategoryModel.translation(category, "name", category),
                 "description": IntentCategoryModel.translation(category, "description", None),
                 "intent_category": category,
                 "weight": list(IntentCategoryModel._get_translations().keys()).index(category),

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