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

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

Jack Ha 8 лет назад
Родитель
Сommit
1ad39a3332

+ 1 - 1
cura/CuraApplication.py

@@ -503,7 +503,7 @@ class CuraApplication(QtApplication):
 
         qmlRegisterType(cura.Settings.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
         qmlRegisterType(cura.Settings.ProfilesModel, "Cura", 1, 0, "ProfilesModel")
-        qmlRegisterType(cura.Settings.ProfilesPageModel, "Cura", 1, 0, "ProfilesPageModel")
+        qmlRegisterType(cura.Settings.QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel")
         qmlRegisterType(cura.Settings.MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
         qmlRegisterType(cura.Settings.QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
 

+ 21 - 1
cura/QualityManager.py

@@ -42,7 +42,12 @@ class QualityManager:
     #   \return the matching quality changes containers \type{List[ContainerInstance]}
     def findQualityChangesByName(self, quality_changes_name, machine_definition=None):
         criteria = {"type": "quality_changes", "name": quality_changes_name}
-        return self._getFilteredContainersForStack(machine_definition, [], **criteria)
+        result = self._getFilteredContainersForStack(machine_definition, [], **criteria)
+
+        criteria = {"type": "quality_changes", "global_profile": quality_changes_name}
+        result.extend(self._getFilteredContainersForStack(machine_definition, [], **criteria))
+
+        return result
 
     ##  Fetch the list of available quality types for this combination of machine definition and materials.
     #
@@ -60,6 +65,11 @@ class QualityManager:
 
         return list(common_quality_types)
 
+    ##  Fetches a dict of quality types names to quality profiles for a combination of machine and material.
+    #
+    #   \param machine_definition \type{DefinitionContainer} the machine definition.
+    #   \param material \type{ContainerInstance} the material.
+    #   \return \type{Dict[str, ContainerInstance]} the dict of suitable quality type names mapping to qualities.
     def __fetchQualityTypeDictForMaterial(self, machine_definition, material):
         qualities = self.findAllQualitiesForMachineMaterial(machine_definition, material)
         quality_type_dict = {}
@@ -87,6 +97,11 @@ class QualityManager:
             result = self._getFilteredContainersForStack(machine_definition, [basic_material], **criteria)
         return result[0] if result else None
 
+    ##  Find all suitable qualities for a combination of machine and material.
+    #
+    #   \param machine_definition \type{DefinitionContainer} the machine definition.
+    #   \param material_container \type{ContainerInstance} the material.
+    #   \return \type{List[ContainerInstance]} the list of suitable qualities.
     def findAllQualitiesForMachineMaterial(self, machine_definition, material_container):
         criteria = {"type": "quality" }
         result = self._getFilteredContainersForStack(machine_definition, [material_container], **criteria)
@@ -95,6 +110,11 @@ class QualityManager:
             result = self._getFilteredContainersForStack(machine_definition, [basic_material], **criteria)
         return result
 
+    ##  Fetch a more basic version of a material.
+    #
+    #   This tries to find a generic or basic version of the given material.
+    #   \param material_container \type{InstanceContainer} the material
+    #   \return \type{Option[InstanceContainer]} the basic material or None if one could not be found.
     def _getBasicMaterial(self, material_container):
         base_material = material_container.getMetaDataEntry("material")
         if base_material:

+ 34 - 2
cura/Settings/ContainerManager.py

@@ -467,6 +467,8 @@ class ContainerManager(QObject):
             base_name = active_quality_name
         unique_name = self._container_registry.uniqueName(base_name)
 
+        global_changes = None
+
         # Go through the active stacks and create quality_changes containers from the user containers.
         for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
             user_container = stack.getTop()
@@ -482,6 +484,11 @@ class ContainerManager(QObject):
                                                      extruder_id)
             self._performMerge(new_changes, user_container)
 
+            if stack is global_stack:
+                global_changes = new_changes
+            else:
+                new_changes.setMetaDataEntry("global_profile", global_changes.getId())
+
             self._container_registry.addContainer(new_changes)
             stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes)
 
@@ -563,9 +570,16 @@ class ContainerManager(QObject):
         container_registry = self._container_registry
 
         containers_to_rename = self._container_registry.findInstanceContainers(type = "quality_changes", name = quality_name)
+        containers_to_rename.extend(self._container_registry.findInstanceContainers(type = "quality_changes", global_profile = quality_name))
+
+        global_changes_id = ""
         for container in containers_to_rename:
             stack_id = container.getMetaDataEntry("extruder", global_stack.getId())
             container_registry.renameContainer(container.getId(), new_name, self._createUniqueId(stack_id, new_name))
+            if "global_profile" not in container.getMetaData():
+                global_changes_id = container.getId()
+            else:
+                container.setMetaDataEntry("global_profile", global_changes_id)
 
         if not containers_to_rename:
             UM.Logger.log("e", "Unable to rename %s, because we could not find the profile", quality_name)
@@ -628,8 +642,9 @@ class ContainerManager(QObject):
         new_change_instances = []
 
         # Handle the global stack first.
-        new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, None)
-        new_change_instances.append(new_changes)
+        global_changes = self._createQualityChanges(quality_container, new_name, machine_definition, None)
+        new_changes.addMetaDataEntry("global_profile", global_changes.getId())
+        new_change_instances.append(global_changes)
         self._container_registry.addContainer(new_changes)
 
         # Handle the extruders if present.
@@ -638,6 +653,7 @@ class ContainerManager(QObject):
             for key in extruders:
                 value = extruders[key]
                 new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, value)
+                new_changes.addMetaDataEntry("global_profile", global_changes.getId())
                 new_change_instances.append(new_changes)
                 self._container_registry.addContainer(new_changes)
 
@@ -646,10 +662,16 @@ class ContainerManager(QObject):
     #  Duplicate a quality changes container
     def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition):
         new_change_instances = []
+        profile_index = -1
+        global_changes_id = ""
         for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name,
                                                               machine_definition):
             new_unique_id = self._createUniqueId(container.getId(), base_name)
             new_container = container.duplicate(new_unique_id, base_name)
+            if profile_index >= 0:
+                new_changes.setMetaDataEntry("global_profile", global_changes_id)
+            else:
+                global_changes_id = new_unique_id
             new_change_instances.append(new_container)
             self._container_registry.addContainer(new_container)
 
@@ -678,6 +700,16 @@ class ContainerManager(QObject):
         duplicated_container.setDirty(True)
         self._container_registry.addContainer(duplicated_container)
 
+    ##  Get the singleton instance for this class.
+    @classmethod
+    def getInstance(cls):
+        # Note: Explicit use of class name to prevent issues with inheritance.
+        if ContainerManager.__instance is None:
+            ContainerManager.__instance = cls()
+        return ContainerManager.__instance
+
+    __instance = None
+
     # Factory function, used by QML
     @staticmethod
     def createContainerManager(engine, js_engine):

+ 54 - 10
cura/Settings/CuraContainerRegistry.py

@@ -16,6 +16,9 @@ from UM.Platform import Platform
 from UM.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with.
 from UM.Util import parseBool
 
+from cura.Settings.ExtruderManager import ExtruderManager
+from cura.Settings.ContainerManager import ContainerManager
+
 from UM.i18n import i18nCatalog
 catalog = i18nCatalog("cura")
 
@@ -128,8 +131,15 @@ class CuraContainerRegistry(ContainerRegistry):
             return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, "Invalid path")}
 
         plugin_registry = PluginRegistry.getInstance()
-        container_registry = ContainerRegistry.getInstance()
         extension = file_name.split(".")[-1]
+
+        global_container_stack = Application.getInstance().getGlobalContainerStack()
+        if not global_container_stack:
+            return
+
+        machine_extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()))
+        machine_extruders.sort(key = lambda k: k.getMetaDataEntry("position"))
+
         for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
             if meta_data["profile_reader"][0]["extension"] != extension:
                 continue
@@ -148,17 +158,49 @@ class CuraContainerRegistry(ContainerRegistry):
                     self._configureProfile(profile, name_seed)
                     return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) }
                 else:
+                    profile_index = -1
+                    global_profile = None
+
                     for profile in profile_or_list:
-                        extruder_id = profile.getMetaDataEntry("extruder")
-                        if extruder_id:
-                            profile_name = "%s_%s" % (extruder_id, name_seed)
+                        if profile_index >= 0:
+                            if len(machine_extruders) > profile_index:
+                                extruder_id = machine_extruders[profile_index].getBottom().getId()
+                                profile_name = "%s_%s" % (extruder_id, name_seed)
+                                # Ensure the extruder profiles get non-conflicting names
+                                # NB: these are not user-facing
+                                if "extruder" in profile.getMetaData():
+                                    profile.setMetaDataEntry("extruder", extruder_id)
+                                else:
+                                    profile.addMetaDataEntry("extruder", extruder_id)
+                                if "global_profile" in profile.getMetaData():
+                                    profile.setMetaDataEntry("global_profile", global_profile.getId())
+                                else:
+                                    profile.addMetaDataEntry("global_profile", global_profile.getId())
+                            elif profile_index == 0:
+                                # Importing a multiextrusion profile into a single extrusion machine; merge 1st extruder profile into global profile
+                                profile._id = self.uniqueName("temporary_profile")
+                                self.addContainer(profile)
+                                ContainerManager.getInstance().mergeContainers(global_profile.getId(), profile.getId())
+                                self.removeContainer(profile.getId())
+                                break
+                            else:
+                                # The imported composite profile has a profile for an extruder that this machine does not have. Ignore this extruder-profile
+                                break
                         else:
+                            global_profile = profile
                             profile_name = name_seed
-                        new_name = container_registry.uniqueName(profile_name)
+                        new_name = self.uniqueName(profile_name)
+
                         profile.setDirty(True)  # Ensure the profiles are correctly saved
+                        if "type" in profile.getMetaData():
+                            profile.setMetaDataEntry("type", "quality_changes")
+                        else:
+                            profile.addMetaDataEntry("type", "quality_changes")
                         self._configureProfile(profile, profile_name)
                         profile.setName(new_name)
 
+                        profile_index += 1
+
                     return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())}
 
         # If it hasn't returned by now, none of the plugins loaded the profile successfully.
@@ -171,7 +213,7 @@ class CuraContainerRegistry(ContainerRegistry):
         profile._id = new_id
 
         if self._machineHasOwnQualities():
-            profile.setDefinition(self._activeDefinition())
+            profile.setDefinition(self._activeQualityDefinition())
             if self._machineHasOwnMaterials():
                 profile.addMetaDataEntry("material", self._activeMaterialId())
         else:
@@ -192,12 +234,14 @@ class CuraContainerRegistry(ContainerRegistry):
                 result.append( (plugin_id, meta_data) )
         return result
 
-    ##  Gets the active definition
-    #   \return the active definition object or None if there is no definition
-    def _activeDefinition(self):
+    ##  Get the definition to use to select quality profiles for the active machine
+    #   \return the active quality definition object or None if there is no quality definition
+    def _activeQualityDefinition(self):
         global_container_stack = Application.getInstance().getGlobalContainerStack()
         if global_container_stack:
-            definition = global_container_stack.getBottom()
+            definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(global_container_stack.getBottom())
+            definition = self.findDefinitionContainers(id=definition_id)[0]
+
             if definition:
                 return definition
         return None

+ 9 - 3
cura/Settings/ExtrudersModel.py

@@ -29,6 +29,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
     #   containers.
     IndexRole = Qt.UserRole + 4
 
+    # The ID of the definition of the extruder.
+    DefinitionRole = Qt.UserRole + 5
+
     ##  List of colours to display if there is no material or the material has no known
     #   colour.
     defaultColors = ["#ffc924", "#86ec21", "#22eeee", "#245bff", "#9124ff", "#ff24c8"]
@@ -44,6 +47,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
         self.addRoleName(self.NameRole, "name")
         self.addRoleName(self.ColorRole, "color")
         self.addRoleName(self.IndexRole, "index")
+        self.addRoleName(self.DefinitionRole, "definition")
 
         self._add_global = False
         self._simple_names = False
@@ -51,8 +55,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
         self._active_extruder_stack = None
 
         #Listen to changes.
+        UM.Application.getInstance().globalContainerStackChanged.connect(self._updateExtruders)
         manager = ExtruderManager.getInstance()
-        manager.globalContainerStackDefinitionChanged.connect(self._updateExtruders) #When the global stack changes to a printer with different extruders.
 
         self._updateExtruders()
 
@@ -126,7 +130,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
                     "id": global_container_stack.getId(),
                     "name": "Global",
                     "color": color,
-                    "index": -1
+                    "index": -1,
+                    "definition": ""
                 }
                 items.append(item)
                 changed = True
@@ -148,7 +153,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
                     "id": extruder.getId(),
                     "name": extruder_name,
                     "color": color,
-                    "index": position
+                    "index": position,
+                    "definition": extruder.getBottom().getId()
                 }
                 items.append(item)
                 changed = True

+ 7 - 5
cura/Settings/MachineManager.py

@@ -461,8 +461,8 @@ class MachineManager(QObject):
 
     @pyqtProperty(str, notify=activeQualityChanged)
     def activeQualityName(self):
-        if self._active_container_stack:
-            quality = self._active_container_stack.findContainer({"type": "quality_changes"})
+        if self._active_container_stack and self._global_container_stack:
+            quality = self._global_container_stack.findContainer({"type": "quality_changes"})
             if quality and quality != self._empty_quality_changes_container:
                 return quality.getName()
             quality = self._active_container_stack.findContainer({"type": "quality"})
@@ -544,6 +544,7 @@ class MachineManager(QObject):
 
         material_index = self._active_container_stack.getContainerIndex(old_material)
         self._active_container_stack.replaceContainer(material_index, material_container)
+        Logger.log("d", "Active material changed")
 
         material_container.nameChanged.connect(self._onMaterialNameChanged)
 
@@ -566,10 +567,11 @@ class MachineManager(QObject):
                                    [material_container])
         if not candidate_quality:
             # Fall back to a quality
-            new_quality_id = quality_manager.findQualityByQualityType(None,
+            new_quality = quality_manager.findQualityByQualityType(None,
                                 quality_manager.getWholeMachineDefinition(machine_definition),
                                 [material_container])
-
+            if new_quality:
+                new_quality_id = new_quality.getId()
         else:
             if not old_quality_changes:
                 new_quality_id = candidate_quality.getId()
@@ -588,7 +590,7 @@ class MachineManager(QObject):
             self.blurSettings.emit()
             variant_index = self._active_container_stack.getContainerIndex(old_variant)
             self._active_container_stack.replaceContainer(variant_index, containers[0])
-
+            Logger.log("d", "Active variant changed")
             preferred_material = None
             if old_material:
                 preferred_material_name = old_material.getName()

+ 5 - 0
cura/Settings/ProfilesModel.py

@@ -6,6 +6,7 @@ from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel
 
 from cura.QualityManager import QualityManager
 from cura.Settings.ExtruderManager import ExtruderManager
+from cura.Settings.MachineManager import MachineManager
 
 ##  QML Model for listing the current list of valid quality profiles.
 #
@@ -15,6 +16,10 @@ class ProfilesModel(InstanceContainersModel):
 
         Application.getInstance().globalContainerStackChanged.connect(self._update)
 
+        Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update)
+        Application.getInstance().getMachineManager().activeStackChanged.connect(self._update)
+        Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update)
+
     ##  Fetch the list of containers to display.
     #
     #   See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers().

+ 1 - 1
cura/Settings/ProfilesPageModel.py → cura/Settings/QualityAndUserProfilesModel.py

@@ -8,7 +8,7 @@ from cura.Settings.ProfilesModel import ProfilesModel
 
 ##  QML Model for listing the current list of valid quality and quality changes profiles.
 #
-class ProfilesPageModel(ProfilesModel):
+class QualityAndUserProfilesModel(ProfilesModel):
     def __init__(self, parent = None):
         super().__init__(parent)
 

+ 15 - 2
cura/Settings/QualitySettingsModel.py

@@ -25,6 +25,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
         self._container_registry = UM.Settings.ContainerRegistry.getInstance()
 
         self._extruder_id = None
+        self._extruder_definition_id = None
         self._quality = None
         self._material = None
 
@@ -46,6 +47,17 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
     def extruderId(self):
         return self._extruder_id
 
+    def setExtruderDefinition(self, extruder_definition):
+        if extruder_definition != self._extruder_definition_id:
+            self._extruder_definition_id = extruder_definition
+            self._update()
+            self.extruderDefinitionChanged.emit()
+
+    extruderDefinitionChanged = pyqtSignal()
+    @pyqtProperty(str, fset = setExtruderDefinition, notify = extruderDefinitionChanged)
+    def extruderDefinition(self):
+        return self._extruder_definition_id
+
     def setQuality(self, quality):
         if quality != self._quality:
             self._quality = quality
@@ -138,8 +150,9 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel):
 
         if quality_changes_container:
             criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()}
-            if self._extruder_id != "":
-                criteria["extruder"] = self._extruder_id
+            if self._extruder_definition_id != "":
+                criteria["extruder"] = self._extruder_definition_id
+                criteria["name"] = "%s_%s" % (self._extruder_definition_id, quality_changes_container.getName())
             else:
                 criteria["extruder"] = None
 

+ 1 - 1
cura/Settings/__init__.py

@@ -13,4 +13,4 @@ from .SettingOverrideDecorator import SettingOverrideDecorator
 from .QualitySettingsModel import QualitySettingsModel
 from .SettingInheritanceManager import SettingInheritanceManager
 from .ProfilesModel import ProfilesModel
-from .ProfilesPageModel import ProfilesPageModel
+from .QualityAndUserProfilesModel import QualityAndUserProfilesModel

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