Browse Source

Merge pull request #3033 from Ultimaker/CURA-4708_fix_definition_changes_extruder_stacks

CURA-4708 Fix definition_changes containers for extruder stacks
ChrisTerBeke 7 years ago
parent
commit
0b7519dff2

+ 43 - 3
cura/Settings/CuraContainerRegistry.py

@@ -14,6 +14,7 @@ from UM.Decorators import override
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.Settings.ContainerStack import ContainerStack
 from UM.Settings.ContainerStack import ContainerStack
 from UM.Settings.InstanceContainer import InstanceContainer
 from UM.Settings.InstanceContainer import InstanceContainer
+from UM.Settings.SettingInstance import SettingInstance
 from UM.Application import Application
 from UM.Application import Application
 from UM.Logger import Logger
 from UM.Logger import Logger
 from UM.Message import Message
 from UM.Message import Message
@@ -430,11 +431,42 @@ class CuraContainerRegistry(ContainerRegistry):
         extruder_stack.setDefinition(extruder_definition)
         extruder_stack.setDefinition(extruder_definition)
         extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
         extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
 
 
+        from cura.CuraApplication import CuraApplication
+
+        # create a new definition_changes container for the extruder stack
+        definition_changes_id = self.uniqueName(extruder_stack.getId() + "_settings")
+        definition_changes_name = definition_changes_id
+        definition_changes = InstanceContainer(definition_changes_id)
+        definition_changes.setName(definition_changes_name)
+        definition_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
+        definition_changes.addMetaDataEntry("type", "definition_changes")
+        definition_changes.addMetaDataEntry("definition", extruder_definition.getId())
+
+        # move definition_changes settings if exist
+        for setting_key in definition_changes.getAllKeys():
+            if machine.definition.getProperty(setting_key, "settable_per_extruder"):
+                setting_value = machine.definitionChanges.getProperty(setting_key, "value")
+                if setting_value is not None:
+                    # move it to the extruder stack's definition_changes
+                    setting_definition = machine.getSettingDefinition(setting_key)
+                    new_instance = SettingInstance(setting_definition, definition_changes)
+                    new_instance.setProperty("value", setting_value)
+                    new_instance.resetState()  # Ensure that the state is not seen as a user state.
+                    definition_changes.addInstance(new_instance)
+                    definition_changes.setDirty(True)
+
+                    machine.definitionChanges.removeInstance(setting_key, postpone_emit = True)
+
+        self.addContainer(definition_changes)
+        extruder_stack.setDefinitionChanges(definition_changes)
+
         # create empty user changes container otherwise
         # create empty user changes container otherwise
-        user_container = InstanceContainer(extruder_stack.id + "_user")
+        user_container_id = self.uniqueName(extruder_stack.getId() + "_user")
+        user_container_name = user_container_id
+        user_container = InstanceContainer(user_container_id)
+        user_container.setName(user_container_name)
         user_container.addMetaDataEntry("type", "user")
         user_container.addMetaDataEntry("type", "user")
         user_container.addMetaDataEntry("machine", extruder_stack.getId())
         user_container.addMetaDataEntry("machine", extruder_stack.getId())
-        from cura.CuraApplication import CuraApplication
         user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
         user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
         user_container.setDefinition(machine.definition.getId())
         user_container.setDefinition(machine.definition.getId())
 
 
@@ -444,7 +476,15 @@ class CuraContainerRegistry(ContainerRegistry):
             for user_setting_key in machine.userChanges.getAllKeys():
             for user_setting_key in machine.userChanges.getAllKeys():
                 settable_per_extruder = machine.getProperty(user_setting_key, "settable_per_extruder")
                 settable_per_extruder = machine.getProperty(user_setting_key, "settable_per_extruder")
                 if settable_per_extruder:
                 if settable_per_extruder:
-                    user_container.addInstance(machine.userChanges.getInstance(user_setting_key))
+                    setting_value = machine.getProperty(user_setting_key, "value")
+
+                    setting_definition = machine.getSettingDefinition(user_setting_key)
+                    new_instance = SettingInstance(setting_definition, definition_changes)
+                    new_instance.setProperty("value", setting_value)
+                    new_instance.resetState()  # Ensure that the state is not seen as a user state.
+                    user_container.addInstance(new_instance)
+                    user_container.setDirty(True)
+
                     machine.userChanges.removeInstance(user_setting_key, postpone_emit = True)
                     machine.userChanges.removeInstance(user_setting_key, postpone_emit = True)
 
 
         self.addContainer(user_container)
         self.addContainer(user_container)

+ 29 - 0
cura/Settings/ExtruderStack.py

@@ -8,6 +8,7 @@ from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
 from UM.Settings.ContainerStack import ContainerStack
 from UM.Settings.ContainerStack import ContainerStack
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext
 from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext
+from UM.Settings.SettingInstance import SettingInstance
 
 
 from . import Exceptions
 from . import Exceptions
 from .CuraContainerStack import CuraContainerStack
 from .CuraContainerStack import CuraContainerStack
@@ -16,6 +17,11 @@ from .ExtruderManager import ExtruderManager
 if TYPE_CHECKING:
 if TYPE_CHECKING:
     from cura.Settings.GlobalStack import GlobalStack
     from cura.Settings.GlobalStack import GlobalStack
 
 
+
+_EXTRUDER_SPECIFIC_DEFINITION_CHANGES_SETTINGS = ["machine_nozzle_size",
+                                                  "material_diameter"]
+
+
 ##  Represents an Extruder and its related containers.
 ##  Represents an Extruder and its related containers.
 #
 #
 #
 #
@@ -39,6 +45,29 @@ class ExtruderStack(CuraContainerStack):
         # For backward compatibility: Register the extruder with the Extruder Manager
         # For backward compatibility: Register the extruder with the Extruder Manager
         ExtruderManager.getInstance().registerExtruder(self, stack.id)
         ExtruderManager.getInstance().registerExtruder(self, stack.id)
 
 
+        # Now each machine will have at least one extruder stack. If this is the first extruder, the extruder-specific
+        # settings such as nozzle size and material diameter should be moved from the machine's definition_changes to
+        # the this extruder's definition_changes.
+        #
+        # We do this here because it is tooooo expansive to do it in the version upgrade: During the version upgrade,
+        # when we are upgrading a definition_changes container file, there is NO guarantee that other files such as
+        # machine an extruder stack files are upgraded before this, so we cannot read those files assuming they are in
+        # the latest format.
+        if self.getMetaDataEntry("position") == "0":
+            for key in _EXTRUDER_SPECIFIC_DEFINITION_CHANGES_SETTINGS:
+                setting_value = stack.definitionChanges.getProperty(key, "value")
+                if setting_value is None:
+                    continue
+
+                setting_definition = stack.getSettingDefinition(key)
+                new_instance = SettingInstance(setting_definition, self.definitionChanges)
+                new_instance.setProperty("value", setting_value)
+                new_instance.resetState()  # Ensure that the state is not seen as a user state.
+                self.definitionChanges.addInstance(new_instance)
+                self.definitionChanges.setDirty(True)
+
+                stack.definitionChanges.removeInstance(key, postpone_emit = True)
+
     @override(ContainerStack)
     @override(ContainerStack)
     def getNextStack(self) -> Optional["GlobalStack"]:
     def getNextStack(self) -> Optional["GlobalStack"]:
         return super().getNextStack()
         return super().getNextStack()

+ 1 - 138
plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py

@@ -122,26 +122,6 @@ class VersionUpgrade30to31(VersionUpgrade):
             if len(all_quality_changes) <= 1 and not parser.has_option("metadata", "extruder"):
             if len(all_quality_changes) <= 1 and not parser.has_option("metadata", "extruder"):
                 self._createExtruderQualityChangesForSingleExtrusionMachine(filename, parser)
                 self._createExtruderQualityChangesForSingleExtrusionMachine(filename, parser)
 
 
-        if parser["metadata"]["type"] == "definition_changes":
-            if parser["general"]["definition"] == "custom":
-
-                # We are only interested in machine_nozzle_size
-                if parser.has_option("values", "machine_nozzle_size"):
-                    machine_nozzle_size = parser["values"]["machine_nozzle_size"]
-
-                    machine_extruder_count = '1' # by default it is 1 and the value cannot be stored in the global stack
-                    if parser.has_option("values", "machine_extruder_count"):
-                        machine_extruder_count = parser["values"]["machine_extruder_count"]
-
-                    if machine_extruder_count == '1':
-                        definition_name = parser["general"]["name"]
-                        machine_extruders = self._getSingleExtrusionMachineExtruders(definition_name)
-
-                        # For single extruder machine we need only first extruder
-                        if len(machine_extruders) != 0:
-                            self._updateSingleExtruderDefinitionFile(machine_extruders, machine_nozzle_size)
-                            parser.remove_option("values", "machine_nozzle_size")
-
         # Update version numbers
         # Update version numbers
         parser["general"]["version"] = "2"
         parser["general"]["version"] = "2"
         parser["metadata"]["setting_version"] = "4"
         parser["metadata"]["setting_version"] = "4"
@@ -220,123 +200,6 @@ class VersionUpgrade30to31(VersionUpgrade):
 
 
         return quality_changes_containers
         return quality_changes_containers
 
 
-    def _getSingleExtrusionMachineExtruders(self, definition_name):
-
-        machine_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.MachineStack)
-
-        machine_instance_id = None
-
-        # Find machine instances
-        for item in os.listdir(machine_instances_dir):
-            file_path = os.path.join(machine_instances_dir, item)
-            if not os.path.isfile(file_path):
-                continue
-
-            parser = configparser.ConfigParser(interpolation=None)
-            try:
-                parser.read([file_path])
-            except:
-                # skip, it is not a valid stack file
-                continue
-
-            if not parser.has_option("metadata", "type"):
-                continue
-            if "machine" != parser["metadata"]["type"]:
-                continue
-
-            if not parser.has_option("general", "id"):
-                continue
-
-            id = parser["general"]["id"]
-            if id + "_settings" != definition_name:
-                continue
-            else:
-                machine_instance_id = id
-                break
-
-        if machine_instance_id is not None:
-
-            extruders_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
-                        #"machine",[extruders]
-            extruder_instances = []
-
-            # Find all custom extruders for found machines
-            for item in os.listdir(extruders_instances_dir):
-                file_path = os.path.join(extruders_instances_dir, item)
-                if not os.path.isfile(file_path):
-                    continue
-
-                parser = configparser.ConfigParser(interpolation=None)
-                try:
-                    parser.read([file_path])
-                except:
-                    # skip, it is not a valid stack file
-                    continue
-
-                if not parser.has_option("metadata", "type"):
-                    continue
-                if "extruder_train" != parser["metadata"]["type"]:
-                    continue
-
-                if not parser.has_option("metadata", "machine"):
-                    continue
-                if not parser.has_option("metadata", "position"):
-                    continue
-
-                if machine_instance_id != parser["metadata"]["machine"]:
-                    continue
-
-                extruder_instances.append(parser)
-
-        return extruder_instances
-
-    # Find extruder definition at index 0 and update its values
-    def _updateSingleExtruderDefinitionFile(self, extruder_instances_per_machine, machine_nozzle_size):
-
-        defintion_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.DefinitionChangesContainer)
-
-        for item in os.listdir(defintion_instances_dir):
-            file_path = os.path.join(defintion_instances_dir, item)
-            if not os.path.isfile(file_path):
-                continue
-
-            parser = configparser.ConfigParser(interpolation=None)
-            try:
-                parser.read([file_path])
-            except:
-                # skip, it is not a valid stack file
-                continue
-
-            if not parser.has_option("general", "name"):
-                continue
-            name = parser["general"]["name"]
-            custom_extruder_at_0_position = None
-            for extruder_instance in extruder_instances_per_machine:
-
-                definition_position = extruder_instance["metadata"]["position"]
-
-                if definition_position == "0":
-                    custom_extruder_at_0_position = extruder_instance
-                    break
-
-            # If not null, then parsed file is for first extuder and then can be updated. I need to update only
-            # first, because this update for single extuder machine
-            if custom_extruder_at_0_position is not None:
-
-                #Add new value
-                parser["values"]["machine_nozzle_size"] = machine_nozzle_size
-
-                definition_output = io.StringIO()
-                parser.write(definition_output)
-
-                with open(file_path, "w") as f:
-                    f.write(definition_output.getvalue())
-
-                return True
-
-        return False
-
-
     def _createExtruderQualityChangesForSingleExtrusionMachine(self, filename, global_quality_changes):
     def _createExtruderQualityChangesForSingleExtrusionMachine(self, filename, global_quality_changes):
         suffix = "_" + quote_plus(global_quality_changes["general"]["name"].lower())
         suffix = "_" + quote_plus(global_quality_changes["general"]["name"].lower())
         machine_name = os.path.os.path.basename(filename).replace(".inst.cfg", "").replace(suffix, "")
         machine_name = os.path.os.path.basename(filename).replace(".inst.cfg", "").replace(suffix, "")
@@ -369,4 +232,4 @@ class VersionUpgrade30to31(VersionUpgrade):
         quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
         quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
 
 
         with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w") as f:
         with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w") as f:
-            f.write(extruder_quality_changes_output.getvalue())
+            f.write(extruder_quality_changes_output.getvalue())

+ 21 - 0
resources/definitions/fdmextruder.def.json

@@ -181,6 +181,27 @@
                 }
                 }
             }
             }
         },
         },
+        "material": {
+            "label": "Material",
+            "icon": "category_material",
+            "description": "Material",
+            "type": "category",
+            "children": {
+                "material_diameter": {
+                    "label": "Diameter",
+                    "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.",
+                    "unit": "mm",
+                    "type": "float",
+                    "default_value": 2.85,
+                    "minimum_value": "0.0001",
+                    "minimum_value_warning": "0.4",
+                    "maximum_value_warning": "3.5",
+                    "enabled": "machine_gcode_flavor != \"UltiGCode\"",
+                    "settable_per_mesh": false,
+                    "settable_per_extruder": true
+                }
+            }
+        },
         "platform_adhesion":
         "platform_adhesion":
         {
         {
             "label": "Build Plate Adhesion",
             "label": "Build Plate Adhesion",