Просмотр исходного кода

Merge branch 'master' into feature_favorite_materials

Contributes to CURA-5162, CURA-5378
Ian Paschal 6 лет назад
Родитель
Сommit
f6b43bd9ab

+ 1 - 0
.gitignore

@@ -15,6 +15,7 @@ LC_MESSAGES
 .cache
 *.qmlc
 .mypy_cache
+.pytest_cache
 
 #MacOS
 .DS_Store

+ 5 - 1
cura/BuildVolume.py

@@ -242,6 +242,8 @@ class BuildVolume(SceneNode):
 
                 # Mark the node as outside build volume if the set extruder is disabled
                 extruder_position = node.callDecoration("getActiveExtruderPosition")
+                if extruder_position not in self._global_container_stack.extruders:
+                    continue
                 if not self._global_container_stack.extruders[extruder_position].isEnabled:
                     node.setOutsideBuildArea(True)
                     continue
@@ -561,7 +563,9 @@ class BuildVolume(SceneNode):
 
             camera = Application.getInstance().getController().getCameraTool()
             if camera:
-                camera.setZoomRange(min = 1, max = self.getDiagonalSize() * 5) #You can zoom out up to 5 times the diagonal. This gives some space around the volume.
+                diagonal = self.getDiagonalSize()
+                if diagonal > 1:
+                    camera.setZoomRange(min = 0.1, max = diagonal * 5) #You can zoom out up to 5 times the diagonal. This gives some space around the volume.
 
     def _onEngineCreated(self):
         self._engine_ready = True

+ 23 - 59
cura/CuraApplication.py

@@ -1,11 +1,10 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
-import copy
 import os
 import sys
 import time
-from typing import cast, TYPE_CHECKING, Optional
+from typing import cast, TYPE_CHECKING
 
 import numpy
 
@@ -105,6 +104,7 @@ from cura.Settings.ExtrudersModel import ExtrudersModel
 from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
 from cura.Settings.ContainerManager import ContainerManager
 from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
+import cura.Settings.cura_empty_instance_containers
 
 from cura.ObjectsModel import ObjectsModel
 
@@ -215,7 +215,6 @@ class CuraApplication(QtApplication):
 
         self._message_box_callback = None
         self._message_box_callback_arguments = []
-        self._preferred_mimetype = ""
         self._i18n_catalog = None
 
         self._currently_loading_files = []
@@ -368,42 +367,23 @@ class CuraApplication(QtApplication):
         # Add empty variant, material and quality containers.
         # Since they are empty, they should never be serialized and instead just programmatically created.
         # We need them to simplify the switching between materials.
-        empty_container = self._container_registry.getEmptyInstanceContainer()
-        self.empty_container = empty_container
-
-        empty_definition_changes_container = copy.deepcopy(empty_container)
-        empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes")
-        empty_definition_changes_container.setMetaDataEntry("type", "definition_changes")
-        self._container_registry.addContainer(empty_definition_changes_container)
-        self.empty_definition_changes_container = empty_definition_changes_container
-
-        empty_variant_container = copy.deepcopy(empty_container)
-        empty_variant_container.setMetaDataEntry("id", "empty_variant")
-        empty_variant_container.setMetaDataEntry("type", "variant")
-        self._container_registry.addContainer(empty_variant_container)
-        self.empty_variant_container = empty_variant_container
-
-        empty_material_container = copy.deepcopy(empty_container)
-        empty_material_container.setMetaDataEntry("id", "empty_material")
-        empty_material_container.setMetaDataEntry("type", "material")
-        self._container_registry.addContainer(empty_material_container)
-        self.empty_material_container = empty_material_container
-
-        empty_quality_container = copy.deepcopy(empty_container)
-        empty_quality_container.setMetaDataEntry("id", "empty_quality")
-        empty_quality_container.setName("Not Supported")
-        empty_quality_container.setMetaDataEntry("quality_type", "not_supported")
-        empty_quality_container.setMetaDataEntry("type", "quality")
-        empty_quality_container.setMetaDataEntry("supported", False)
-        self._container_registry.addContainer(empty_quality_container)
-        self.empty_quality_container = empty_quality_container
-
-        empty_quality_changes_container = copy.deepcopy(empty_container)
-        empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes")
-        empty_quality_changes_container.setMetaDataEntry("type", "quality_changes")
-        empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported")
-        self._container_registry.addContainer(empty_quality_changes_container)
-        self.empty_quality_changes_container = empty_quality_changes_container
+        self.empty_container = cura.Settings.cura_empty_instance_containers.empty_container
+
+        self._container_registry.addContainer(
+            cura.Settings.cura_empty_instance_containers.empty_definition_changes_container)
+        self.empty_definition_changes_container = cura.Settings.cura_empty_instance_containers.empty_definition_changes_container
+
+        self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_variant_container)
+        self.empty_variant_container = cura.Settings.cura_empty_instance_containers.empty_variant_container
+
+        self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_material_container)
+        self.empty_material_container = cura.Settings.cura_empty_instance_containers.empty_material_container
+
+        self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_quality_container)
+        self.empty_quality_container = cura.Settings.cura_empty_instance_containers.empty_quality_container
+
+        self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_quality_changes_container)
+        self.empty_quality_changes_container = cura.Settings.cura_empty_instance_containers.empty_quality_changes_container
 
     # Initializes the version upgrade manager with by providing the paths for each resource type and the latest
     # versions.
@@ -516,9 +496,6 @@ class CuraApplication(QtApplication):
         self.applicationShuttingDown.connect(self.saveSettings)
         self.engineCreatedSignal.connect(self._onEngineCreated)
 
-        self.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
-        self._onGlobalContainerChanged()
-
         self.getCuraSceneController().setActiveBuildPlate(0)  # Initialize
 
         CuraApplication.Created = True
@@ -782,7 +759,10 @@ class CuraApplication(QtApplication):
         # Initialize camera
         root = controller.getScene().getRoot()
         camera = Camera("3d", root)
-        camera.setPosition(Vector(-80, 250, 700) * self.getBuildVolume().getDiagonalSize() / 375)
+        diagonal = self.getBuildVolume().getDiagonalSize()
+        if diagonal < 1: #No printer added yet. Set a default camera distance for normal-sized printers.
+            diagonal = 375
+        camera.setPosition(Vector(-80, 250, 700) * diagonal / 375)
         camera.setPerspective(True)
         camera.lookAt(Vector(0, 0, 0))
         controller.getScene().setActiveCamera("3d")
@@ -999,30 +979,14 @@ class CuraApplication(QtApplication):
             self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition())
             self._camera_animation.start()
 
-    def _onGlobalContainerChanged(self):
-        if self._global_container_stack is not None:
-            machine_file_formats = [file_type.strip() for file_type in self._global_container_stack.getMetaDataEntry("file_formats").split(";")]
-            new_preferred_mimetype = ""
-            if machine_file_formats:
-                new_preferred_mimetype =  machine_file_formats[0]
-
-            if new_preferred_mimetype != self._preferred_mimetype:
-                self._preferred_mimetype = new_preferred_mimetype
-                self.preferredOutputMimetypeChanged.emit()
-
     requestAddPrinter = pyqtSignal()
     activityChanged = pyqtSignal()
     sceneBoundingBoxChanged = pyqtSignal()
-    preferredOutputMimetypeChanged = pyqtSignal()
 
     @pyqtProperty(bool, notify = activityChanged)
     def platformActivity(self):
         return self._platform_activity
 
-    @pyqtProperty(str, notify=preferredOutputMimetypeChanged)
-    def preferredOutputMimetype(self):
-        return self._preferred_mimetype
-
     @pyqtProperty(str, notify = sceneBoundingBoxChanged)
     def getSceneBoundingBoxString(self):
         return self._i18n_catalog.i18nc("@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm.", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()}

+ 2 - 0
cura/OneAtATimeIterator.py

@@ -76,6 +76,8 @@ class OneAtATimeIterator(Iterator):
                 continue
 
             bounding_box = node.getBoundingBox()
+            if not bounding_box:
+                continue
             from UM.Math.Polygon import Polygon
             bounding_box_polygon = Polygon([[bounding_box.left, bounding_box.front],
                                             [bounding_box.left, bounding_box.back],

+ 7 - 8
cura/Settings/CuraContainerStack.py

@@ -1,7 +1,7 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
-from typing import Any, cast, List, Optional, Union
+from typing import Any, cast, List, Optional
 from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject
 
 from UM.Application import Application
@@ -13,6 +13,7 @@ from UM.Settings.InstanceContainer import InstanceContainer
 from UM.Settings.DefinitionContainer import DefinitionContainer
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.Settings.Interfaces import ContainerInterface, DefinitionContainerInterface
+from cura.Settings import cura_empty_instance_containers
 
 from . import Exceptions
 
@@ -39,14 +40,12 @@ class CuraContainerStack(ContainerStack):
     def __init__(self, container_id: str) -> None:
         super().__init__(container_id)
 
-        self._container_registry = ContainerRegistry.getInstance() #type: ContainerRegistry
+        self._empty_instance_container = cura_empty_instance_containers.empty_container #type: InstanceContainer
 
-        self._empty_instance_container = self._container_registry.getEmptyInstanceContainer() #type: InstanceContainer
-
-        self._empty_quality_changes = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0] #type: InstanceContainer
-        self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] #type: InstanceContainer
-        self._empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0] #type: InstanceContainer
-        self._empty_variant = self._container_registry.findInstanceContainers(id = "empty_variant")[0] #type: InstanceContainer
+        self._empty_quality_changes = cura_empty_instance_containers.empty_quality_changes_container #type: InstanceContainer
+        self._empty_quality = cura_empty_instance_containers.empty_quality_container #type: InstanceContainer
+        self._empty_material = cura_empty_instance_containers.empty_material_container #type: InstanceContainer
+        self._empty_variant = cura_empty_instance_containers.empty_variant_container #type: InstanceContainer
 
         self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))] #type: List[ContainerInterface]
         self._containers[_ContainerIndexes.QualityChanges] = self._empty_quality_changes

+ 19 - 8
cura/Settings/CuraStackBuilder.py

@@ -108,16 +108,27 @@ class CuraStackBuilder:
 
         preferred_quality_type = machine_definition.getMetaDataEntry("preferred_quality_type")
         quality_group_dict = quality_manager.getQualityGroups(new_global_stack)
-        quality_group = quality_group_dict.get(preferred_quality_type)
-
-        new_global_stack.quality = quality_group.node_for_global.getContainer()
-        if not new_global_stack.quality:
+        if not quality_group_dict:
+            # There is no available quality group, set all quality containers to empty.
             new_global_stack.quality = application.empty_quality_container
-        for position, extruder_stack in new_global_stack.extruders.items():
-            if position in quality_group.nodes_for_extruders and quality_group.nodes_for_extruders[position].getContainer():
-                extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer()
-            else:
+            for extruder_stack in new_global_stack.extruders.values():
                 extruder_stack.quality = application.empty_quality_container
+        else:
+            # Set the quality containers to the preferred quality type if available, otherwise use the first quality
+            # type that's available.
+            if preferred_quality_type not in quality_group_dict:
+                Logger.log("w", "The preferred quality {quality_type} doesn't exist for this set-up. Choosing a random one.".format(quality_type = preferred_quality_type))
+                preferred_quality_type = next(iter(quality_group_dict))
+            quality_group = quality_group_dict.get(preferred_quality_type)
+
+            new_global_stack.quality = quality_group.node_for_global.getContainer()
+            if not new_global_stack.quality:
+                new_global_stack.quality = application.empty_quality_container
+            for position, extruder_stack in new_global_stack.extruders.items():
+                if position in quality_group.nodes_for_extruders and quality_group.nodes_for_extruders[position].getContainer():
+                    extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer()
+                else:
+                    extruder_stack.quality = application.empty_quality_container
 
         # Register the global stack after the extruder stacks are created. This prevents the registry from adding another
         # extruder stack because the global stack didn't have one yet (which is enforced since Cura 3.1).

+ 0 - 3
cura/Settings/ExtruderStack.py

@@ -139,9 +139,6 @@ class ExtruderStack(CuraContainerStack):
         super().deserialize(contents, file_name)
         if "enabled" not in self.getMetaData():
             self.setMetaDataEntry("enabled", "True")
-        stacks = ContainerRegistry.getInstance().findContainerStacks(id=self.getMetaDataEntry("machine", ""))
-        if stacks:
-            self.setNextStack(stacks[0])
 
     def _onPropertiesChanged(self, key: str, properties: Dict[str, Any]) -> None:
         # When there is a setting that is not settable per extruder that depends on a value from a setting that is,

+ 4 - 0
cura/Settings/GlobalStack.py

@@ -61,6 +61,10 @@ class GlobalStack(CuraContainerStack):
             name = self.variant.getName()
         return name
 
+    @pyqtProperty(str, constant = True)
+    def preferred_output_file_formats(self) -> str:
+        return self.getMetaDataEntry("file_formats")
+
     ##  Add an extruder to the list of extruders of this stack.
     #
     #   \param extruder The extruder to add.

+ 56 - 0
cura/Settings/cura_empty_instance_containers.py

@@ -0,0 +1,56 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import copy
+
+from UM.Settings.constant_instance_containers import EMPTY_CONTAINER_ID, empty_container
+
+
+# Empty definition changes
+EMPTY_DEFINITION_CHANGES_CONTAINER_ID = "empty_definition_changes"
+empty_definition_changes_container = copy.deepcopy(empty_container)
+empty_definition_changes_container.setMetaDataEntry("id", EMPTY_DEFINITION_CHANGES_CONTAINER_ID)
+empty_definition_changes_container.setMetaDataEntry("type", "definition_changes")
+
+# Empty variant
+EMPTY_VARIANT_CONTAINER_ID = "empty_variant"
+empty_variant_container = copy.deepcopy(empty_container)
+empty_variant_container.setMetaDataEntry("id", EMPTY_VARIANT_CONTAINER_ID)
+empty_variant_container.setMetaDataEntry("type", "variant")
+
+# Empty material
+EMPTY_MATERIAL_CONTAINER_ID = "empty_material"
+empty_material_container = copy.deepcopy(empty_container)
+empty_material_container.setMetaDataEntry("id", EMPTY_MATERIAL_CONTAINER_ID)
+empty_material_container.setMetaDataEntry("type", "material")
+
+# Empty quality
+EMPTY_QUALITY_CONTAINER_ID = "empty_quality"
+empty_quality_container = copy.deepcopy(empty_container)
+empty_quality_container.setMetaDataEntry("id", EMPTY_QUALITY_CONTAINER_ID)
+empty_quality_container.setName("Not Supported")
+empty_quality_container.setMetaDataEntry("quality_type", "not_supported")
+empty_quality_container.setMetaDataEntry("type", "quality")
+empty_quality_container.setMetaDataEntry("supported", False)
+
+# Empty quality changes
+EMPTY_QUALITY_CHANGES_CONTAINER_ID = "empty_quality_changes"
+empty_quality_changes_container = copy.deepcopy(empty_container)
+empty_quality_changes_container.setMetaDataEntry("id", EMPTY_QUALITY_CHANGES_CONTAINER_ID)
+empty_quality_changes_container.setMetaDataEntry("type", "quality_changes")
+empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported")
+
+
+__all__ = ["EMPTY_CONTAINER_ID",
+           "empty_container",  # For convenience
+           "EMPTY_DEFINITION_CHANGES_CONTAINER_ID",
+           "empty_definition_changes_container",
+           "EMPTY_VARIANT_CONTAINER_ID",
+           "empty_variant_container",
+           "EMPTY_MATERIAL_CONTAINER_ID",
+           "empty_material_container",
+           "EMPTY_QUALITY_CHANGES_CONTAINER_ID",
+           "empty_quality_changes_container",
+           "EMPTY_QUALITY_CONTAINER_ID",
+           "empty_quality_container"
+           ]

+ 5 - 0
plugins/3MFReader/ThreeMFWorkspaceReader.py

@@ -630,6 +630,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
                                                                            type = "extruder_train")
             extruder_stack_dict = {stack.getMetaDataEntry("position"): stack for stack in extruder_stacks}
 
+            # Make sure that those extruders have the global stack as the next stack or later some value evaluation
+            # will fail.
+            for stack in extruder_stacks:
+                stack.setNextStack(global_stack, connect_signals = False)
+
         Logger.log("d", "Workspace loading is checking definitions...")
         # Get all the definition files & check if they exist. If not, add them.
         definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]

Некоторые файлы не были показаны из-за большого количества измененных файлов