Browse Source

Fixes for custom FMD printer material diameter upgrade and storage - CURA-4835

ChrisTerBeke 7 years ago
parent
commit
129f9cc16c

+ 84 - 0
cura/Settings/ExtruderManager.py

@@ -502,6 +502,90 @@ class ExtruderManager(QObject):
     def getInstanceExtruderValues(self, key):
         return ExtruderManager.getExtruderValues(key)
 
+    ##  Updates the material container to a material that matches the material diameter set for the printer
+    def updateMaterialForDiameter(self, extruder_position: int):
+
+        global_stack = Application.getInstance().getGlobalContainerStack()
+        if not global_stack:
+            return
+
+        if not global_stack.getMetaDataEntry("has_materials", False):
+            return
+
+        extruder_stack = global_stack.extruders[str(extruder_position)]
+
+        material_diameter = extruder_stack.material.getProperty("material_diameter", "value")
+        if not material_diameter:
+            # in case of "empty" material
+            material_diameter = 0
+
+        material_approximate_diameter = str(round(material_diameter))
+        machine_diameter = extruder_stack.definitionChanges.getProperty("material_diameter", "value")
+        if not machine_diameter:
+            if extruder_stack.definition.hasProperty("material_diameter", "value"):
+                machine_diameter = extruder_stack.definition.getProperty("material_diameter", "value")
+            else:
+                machine_diameter = global_stack.definition.getProperty("material_diameter", "value")
+        machine_approximate_diameter = str(round(machine_diameter))
+
+        if material_approximate_diameter != machine_approximate_diameter:
+            Logger.log("i", "The the currently active material(s) do not match the diameter set for the printer. Finding alternatives.")
+
+            if global_stack.getMetaDataEntry("has_machine_materials", False):
+                materials_definition = global_stack.definition.getId()
+                has_material_variants = global_stack.getMetaDataEntry("has_variants", False)
+            else:
+                materials_definition = "fdmprinter"
+                has_material_variants = False
+
+            old_material = extruder_stack.material
+            search_criteria = {
+                "type": "material",
+                "approximate_diameter": machine_approximate_diameter,
+                "material": old_material.getMetaDataEntry("material", "value"),
+                "brand": old_material.getMetaDataEntry("brand", "value"),
+                "supplier": old_material.getMetaDataEntry("supplier", "value"),
+                "color_name": old_material.getMetaDataEntry("color_name", "value"),
+                "definition": materials_definition
+            }
+            if has_material_variants:
+                search_criteria["variant"] = extruder_stack.variant.getId()
+
+            container_registry = Application.getInstance().getContainerRegistry()
+            empty_material = container_registry.findInstanceContainers(id = "empty_material")[0]
+
+            if old_material == empty_material:
+                search_criteria.pop("material", None)
+                search_criteria.pop("supplier", None)
+                search_criteria.pop("brand", None)
+                search_criteria.pop("definition", None)
+                search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
+
+            materials = container_registry.findInstanceContainers(**search_criteria)
+            if not materials:
+                # Same material with new diameter is not found, search for generic version of the same material type
+                search_criteria.pop("supplier", None)
+                search_criteria.pop("brand", None)
+                search_criteria["color_name"] = "Generic"
+                materials = container_registry.findInstanceContainers(**search_criteria)
+            if not materials:
+                # Generic material with new diameter is not found, search for preferred material
+                search_criteria.pop("color_name", None)
+                search_criteria.pop("material", None)
+                search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
+                materials = container_registry.findInstanceContainers(**search_criteria)
+            if not materials:
+                # Preferred material with new diameter is not found, search for any material
+                search_criteria.pop("id", None)
+                materials = container_registry.findInstanceContainers(**search_criteria)
+            if not materials:
+                # Just use empty material as a final fallback
+                materials = [empty_material]
+
+            Logger.log("i", "Selecting new material: %s", materials[0].getId())
+
+            extruder_stack.material = materials[0]
+
     ##  Get the value for a setting from a specific extruder.
     #
     #   This is exposed to SettingFunction to use in value functions.

+ 12 - 0
cura/Settings/ExtruderStack.py

@@ -3,6 +3,7 @@
 
 from typing import Any, TYPE_CHECKING, Optional
 
+from UM.Application import Application
 from UM.Decorators import override
 from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
 from UM.Settings.ContainerStack import ContainerStack
@@ -60,6 +61,12 @@ class ExtruderStack(CuraContainerStack):
 
         for key in keys_to_copy:
 
+            # Since material_diameter is not on the extruder definition, we need to add it here
+            # WARNING: this might be very dangerous and should be refactored ASAP!
+            definition = stack.getSettingDefinition(key)
+            if definition:
+                self.definition.addDefinition(definition)
+
             # Only copy the value when this extruder doesn't have the value.
             if self.definitionChanges.hasProperty(key, "value"):
                 continue
@@ -75,6 +82,11 @@ class ExtruderStack(CuraContainerStack):
             self.definitionChanges.addInstance(new_instance)
             self.definitionChanges.setDirty(True)
 
+            # Make sure the material diameter is up to date for the extruder stack.
+            if key == "material_diameter":
+                position = self.getMetaDataEntry("position", "0")
+                Application.getInstance().getExtruderManager().updateMaterialForDiameter(position)
+
             # NOTE: We cannot remove the setting from the global stack's definition changes container because for
             # material diameter, it needs to be applied to all extruders, but here we don't know how many extruders
             # a machine actually has and how many extruders has already been loaded for that machine, so we have to

+ 1 - 76
plugins/MachineSettingsAction/MachineSettingsAction.py

@@ -158,79 +158,4 @@ class MachineSettingsAction(MachineAction):
     @pyqtSlot(int)
     def updateMaterialForDiameter(self, extruder_position: int):
         # Updates the material container to a material that matches the material diameter set for the printer
-        if not self._global_container_stack:
-            return
-
-        if not self._global_container_stack.getMetaDataEntry("has_materials", False):
-            return
-
-        extruder_stack = self._global_container_stack.extruders[str(extruder_position)]
-
-        material_diameter = extruder_stack.material.getProperty("material_diameter", "value")
-        if not material_diameter:
-            # in case of "empty" material
-            material_diameter = 0
-
-        material_approximate_diameter = str(round(material_diameter))
-        machine_diameter = extruder_stack.definitionChanges.getProperty("material_diameter", "value")
-        if not machine_diameter:
-            if extruder_stack.definition.hasProperty("material_diameter", "value"):
-                machine_diameter = extruder_stack.definition.getProperty("material_diameter", "value")
-            else:
-                machine_diameter = self._global_container_stack.definition.getProperty("material_diameter", "value")
-        machine_approximate_diameter = str(round(machine_diameter))
-
-        if material_approximate_diameter != machine_approximate_diameter:
-            Logger.log("i", "The the currently active material(s) do not match the diameter set for the printer. Finding alternatives.")
-
-            if self._global_container_stack.getMetaDataEntry("has_machine_materials", False):
-                materials_definition = self._global_container_stack.definition.getId()
-                has_material_variants = self._global_container_stack.getMetaDataEntry("has_variants", False)
-            else:
-                materials_definition = "fdmprinter"
-                has_material_variants = False
-
-            old_material = extruder_stack.material
-            search_criteria = {
-                "type": "material",
-                "approximate_diameter": machine_approximate_diameter,
-                "material": old_material.getMetaDataEntry("material", "value"),
-                "brand": old_material.getMetaDataEntry("brand", "value"),
-                "supplier": old_material.getMetaDataEntry("supplier", "value"),
-                "color_name": old_material.getMetaDataEntry("color_name", "value"),
-                "definition": materials_definition
-            }
-            if has_material_variants:
-                search_criteria["variant"] = extruder_stack.variant.getId()
-
-            if old_material == self._empty_container:
-                search_criteria.pop("material", None)
-                search_criteria.pop("supplier", None)
-                search_criteria.pop("brand", None)
-                search_criteria.pop("definition", None)
-                search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
-
-            materials = self._container_registry.findInstanceContainers(**search_criteria)
-            if not materials:
-                # Same material with new diameter is not found, search for generic version of the same material type
-                search_criteria.pop("supplier", None)
-                search_criteria.pop("brand", None)
-                search_criteria["color_name"] = "Generic"
-                materials = self._container_registry.findInstanceContainers(**search_criteria)
-            if not materials:
-                # Generic material with new diameter is not found, search for preferred material
-                search_criteria.pop("color_name", None)
-                search_criteria.pop("material", None)
-                search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
-                materials = self._container_registry.findInstanceContainers(**search_criteria)
-            if not materials:
-                # Preferred material with new diameter is not found, search for any material
-                search_criteria.pop("id", None)
-                materials = self._container_registry.findInstanceContainers(**search_criteria)
-            if not materials:
-                # Just use empty material as a final fallback
-                materials = [self._empty_container]
-
-            Logger.log("i", "Selecting new material: %s", materials[0].getId())
-
-            extruder_stack.material = materials[0]
+        Application.getInstance().getExtruderManager().updateMaterialForDiameter(extruder_position)