Browse Source

Merge branch 'master' of github.com:Ultimaker/Cura into 3mf_platform_meshes

Jaime van Kessel 4 years ago
parent
commit
b7081f9c68

+ 6 - 0
cura/API/Account.py

@@ -29,10 +29,12 @@ class Account(QObject):
     # Signal emitted when user logged in or out.
     loginStateChanged = pyqtSignal(bool)
     accessTokenChanged = pyqtSignal()
+    cloudPrintersDetectedChanged = pyqtSignal(bool)
 
     def __init__(self, application: "CuraApplication", parent = None) -> None:
         super().__init__(parent)
         self._application = application
+        self._new_cloud_printers_detected = False
 
         self._error_message = None  # type: Optional[Message]
         self._logged_in = False
@@ -74,6 +76,10 @@ class Account(QObject):
     def isLoggedIn(self) -> bool:
         return self._logged_in
 
+    @pyqtProperty(bool, notify=cloudPrintersDetectedChanged)
+    def newCloudPrintersDetected(self) -> bool:
+        return self._new_cloud_printers_detected
+
     def _onLoginStateChanged(self, logged_in: bool = False, error_message: Optional[str] = None) -> None:
         if error_message:
             if self._error_message:

+ 1 - 1
cura/ApplicationMetadata.py

@@ -13,7 +13,7 @@ DEFAULT_CURA_DEBUG_MODE = False
 # Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
 # example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
 # CuraVersion.py.in template.
-CuraSDKVersion = "7.1.0"
+CuraSDKVersion = "7.2.0"
 
 try:
     from cura.CuraVersion import CuraAppName  # type: ignore

+ 1 - 0
cura/Arranging/Arrange.py

@@ -196,6 +196,7 @@ class Arrange:
                 start_idx = 0
         else:
             start_idx = 0
+        priority = 0
         for priority in self._priority_unique_values[start_idx::step]:
             tryout_idx = numpy.where(self._priority == priority)
             for idx in range(len(tryout_idx[0])):

+ 4 - 0
cura/Machines/MachineNode.py

@@ -171,6 +171,10 @@ class MachineNode(ContainerNode):
                 if variant_name not in self.variants:
                     self.variants[variant_name] = VariantNode(variant["id"], machine = self)
                     self.variants[variant_name].materialsChanged.connect(self.materialsChanged)
+                else:
+                    # Force reloading the materials if the variant already exists or else materals won't be loaded
+                    # when the G-Code flavor changes --> CURA-7354
+                    self.variants[variant_name]._loadAll()
             if not self.variants:
                 self.variants["empty"] = VariantNode("empty_variant", machine = self)
 

+ 1 - 0
cura/PreviewPass.py

@@ -61,6 +61,7 @@ class PreviewPass(RenderPass):
                 self._shader.setUniformValue("u_ambientColor", [0.1, 0.1, 0.1, 1.0])
                 self._shader.setUniformValue("u_specularColor", [0.6, 0.6, 0.6, 1.0])
                 self._shader.setUniformValue("u_shininess", 20.0)
+                self._shader.setUniformValue("u_renderError", 0.0)  # We don't want any error markers!.
                 self._shader.setUniformValue("u_faceId", -1)  # Don't render any selected faces in the preview.
 
         if not self._non_printing_shader:

+ 6 - 3
cura/Settings/ContainerManager.py

@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
 import os
@@ -206,8 +206,11 @@ class ContainerManager(QObject):
         if contents is None:
             return {"status": "error", "message": "Serialization returned None. Unable to write to file"}
 
-        with SaveFile(file_url, "w") as f:
-            f.write(contents)
+        try:
+            with SaveFile(file_url, "w") as f:
+                f.write(contents)
+        except OSError:
+            return {"status": "error", "message": "Unable to write to this location.", "path": file_url}
 
         return {"status": "success", "message": "Successfully exported container", "path": file_url}
 

+ 6 - 0
cura/Settings/SettingOverrideDecorator.py

@@ -94,6 +94,12 @@ class SettingOverrideDecorator(SceneNodeDecorator):
     #
     #   \return An extruder's position, or None if no position info is available.
     def getActiveExtruderPosition(self):
+        # for support_meshes, always use the support_extruder
+        if self.getStack().getProperty("support_mesh", "value"):
+            global_container_stack = Application.getInstance().getGlobalContainerStack()
+            if global_container_stack:
+                return str(global_container_stack.getProperty("support_extruder_nr", "value"))
+
         containers = ContainerRegistry.getInstance().findContainers(id = self.getActiveExtruder())
         if containers:
             container_stack = containers[0]

+ 43 - 1
cura/UI/ObjectsModel.py

@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 from UM.Logger import Logger
 import re
@@ -38,6 +38,9 @@ class ObjectsModel(ListModel):
     OutsideAreaRole = Qt.UserRole + 3
     BuilplateNumberRole = Qt.UserRole + 4
     NodeRole = Qt.UserRole + 5
+    PerObjectSettingsCountRole = Qt.UserRole + 6
+    MeshTypeRole = Qt.UserRole + 7
+    ExtruderNumberRole = Qt.UserRole + 8
 
     def __init__(self, parent = None) -> None:
         super().__init__(parent)
@@ -46,6 +49,9 @@ class ObjectsModel(ListModel):
         self.addRoleName(self.SelectedRole, "selected")
         self.addRoleName(self.OutsideAreaRole, "outside_build_area")
         self.addRoleName(self.BuilplateNumberRole, "buildplate_number")
+        self.addRoleName(self.ExtruderNumberRole, "extruder_number")
+        self.addRoleName(self.PerObjectSettingsCountRole, "per_object_settings_count")
+        self.addRoleName(self.MeshTypeRole, "mesh_type")
         self.addRoleName(self.NodeRole, "node")
 
         Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSceneDelayed)
@@ -172,11 +178,47 @@ class ObjectsModel(ListModel):
 
             node_build_plate_number = node.callDecoration("getBuildPlateNumber")
 
+            node_mesh_type = ""
+            per_object_settings_count = 0
+
+            per_object_stack = node.callDecoration("getStack")
+            if per_object_stack:
+                per_object_settings_count = per_object_stack.getTop().getNumInstances()
+
+                for mesh_type in ["anti_overhang_mesh", "infill_mesh", "cutting_mesh", "support_mesh"]:
+                    if per_object_stack.getProperty(mesh_type, "value"):
+                        node_mesh_type = mesh_type
+                        per_object_settings_count -= 1 # do not count this mesh type setting
+                        break
+
+                if per_object_settings_count > 0:
+                    if node_mesh_type == "support_mesh":
+                        # support meshes only allow support settings
+                        per_object_settings_count = 0
+                        for key in per_object_stack.getTop().getAllKeys():
+                            if per_object_stack.getTop().getInstance(key).definition.isAncestor("support"):
+                                per_object_settings_count += 1
+                    elif node_mesh_type == "anti_overhang_mesh":
+                        # anti overhang meshes ignore per model settings
+                        per_object_settings_count = 0
+
+            extruder_position = node.callDecoration("getActiveExtruderPosition")
+            if extruder_position is None:
+                extruder_number = -1
+            else:
+                extruder_number = int(extruder_position)
+            if node_mesh_type == "anti_overhang_mesh" or node.callDecoration("isGroup"):
+                # for anti overhang meshes and groups the extruder nr is irrelevant
+                extruder_number = -1
+
             nodes.append({
                 "name": node.getName(),
                 "selected": Selection.isSelected(node),
                 "outside_build_area": is_outside_build_area,
                 "buildplate_number": node_build_plate_number,
+                "extruder_number": extruder_number,
+                "per_object_settings_count": per_object_settings_count,
+                "mesh_type": node_mesh_type,
                 "node": node
             })
 

+ 15 - 4
cura/UI/WelcomePagesModel.py

@@ -243,6 +243,10 @@ class WelcomePagesModel(ListModel):
                           {"id": "data_collections",
                            "page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"),
                            },
+                          {"id": "cloud",
+                           "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
+                           "should_show_function": self.shouldShowCloudPage,
+                           },
                           {"id": "add_network_or_local_printer",
                            "page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
                            "next_page_id": "machine_actions",
@@ -253,12 +257,8 @@ class WelcomePagesModel(ListModel):
                            },
                           {"id": "machine_actions",
                            "page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
-                           "next_page_id": "cloud",
                            "should_show_function": self.shouldShowMachineActions,
                            },
-                          {"id": "cloud",
-                           "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
-                           },
                           ]
 
         pages_to_show = all_pages_list
@@ -287,6 +287,17 @@ class WelcomePagesModel(ListModel):
         first_start_actions = self._application.getMachineActionManager().getFirstStartActions(definition_id)
         return len([action for action in first_start_actions if action.needsUserInteraction()]) > 0
 
+    def shouldShowCloudPage(self) -> bool:
+        """
+        The cloud page should be shown only if the user is not logged in
+
+        :return: True if the user is not logged in, False if he/she is
+        """
+        # Import CuraApplication locally or else it fails
+        from cura.CuraApplication import CuraApplication
+        api = CuraApplication.getInstance().getCuraAPI()
+        return not api.account.isLoggedIn
+
     def addPage(self) -> None:
         pass
 

BIN
docs/Cura_Data_Model.odg


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