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

CURA-4708 Fix definition_changes containers for extruder stacks
This commit is contained in:
ChrisTerBeke 2018-01-02 10:53:52 +01:00 committed by GitHub
commit 0b7519dff2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 94 additions and 141 deletions

View File

@ -14,6 +14,7 @@ from UM.Decorators import override
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.SettingInstance import SettingInstance
from UM.Application import Application
from UM.Logger import Logger
from UM.Message import Message
@ -430,11 +431,42 @@ class CuraContainerRegistry(ContainerRegistry):
extruder_stack.setDefinition(extruder_definition)
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
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("machine", extruder_stack.getId())
from cura.CuraApplication import CuraApplication
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
user_container.setDefinition(machine.definition.getId())
@ -444,7 +476,15 @@ class CuraContainerRegistry(ContainerRegistry):
for user_setting_key in machine.userChanges.getAllKeys():
settable_per_extruder = machine.getProperty(user_setting_key, "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)
self.addContainer(user_container)

View File

@ -8,6 +8,7 @@ from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext
from UM.Settings.SettingInstance import SettingInstance
from . import Exceptions
from .CuraContainerStack import CuraContainerStack
@ -16,6 +17,11 @@ from .ExtruderManager import ExtruderManager
if TYPE_CHECKING:
from cura.Settings.GlobalStack import GlobalStack
_EXTRUDER_SPECIFIC_DEFINITION_CHANGES_SETTINGS = ["machine_nozzle_size",
"material_diameter"]
## Represents an Extruder and its related containers.
#
#
@ -39,6 +45,29 @@ class ExtruderStack(CuraContainerStack):
# For backward compatibility: Register the extruder with the Extruder Manager
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)
def getNextStack(self) -> Optional["GlobalStack"]:
return super().getNextStack()

View File

@ -122,26 +122,6 @@ class VersionUpgrade30to31(VersionUpgrade):
if len(all_quality_changes) <= 1 and not parser.has_option("metadata", "extruder"):
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
parser["general"]["version"] = "2"
parser["metadata"]["setting_version"] = "4"
@ -220,123 +200,6 @@ class VersionUpgrade30to31(VersionUpgrade):
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):
suffix = "_" + quote_plus(global_quality_changes["general"]["name"].lower())
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)
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())

View File

@ -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":
{
"label": "Build Plate Adhesion",