Fix project loading

CURA-4617
This commit is contained in:
Lipu Fei 2017-11-27 14:16:40 +01:00
parent 13124ae983
commit 49cac860a8
2 changed files with 110 additions and 71 deletions

View file

@ -408,90 +408,84 @@ class CuraContainerRegistry(ContainerRegistry):
def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id): def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id):
new_extruder_id = extruder_id new_extruder_id = extruder_id
extruder_stack = None
# if extruders are defined in the machine definition use those instead extruder_definitions = self.findDefinitionContainers(id = new_extruder_id)
if machine.extruders and "0" in machine.extruders: if not extruder_definitions:
new_extruder_id = machine.extruders["0"].getId() Logger.log("w", "Could not find definition containers for extruder %s", new_extruder_id)
extruder_stack = machine.extruders["0"] return
# if the extruder stack doesn't exist yet we create and add it extruder_definition = extruder_definitions[0]
if not extruder_stack: unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id)
extruder_definitions = self.findDefinitionContainers(id = new_extruder_id)
if not extruder_definitions:
Logger.log("w", "Could not find definition containers for extruder %s", new_extruder_id)
return
extruder_definition = extruder_definitions[0] extruder_stack = ExtruderStack.ExtruderStack(unique_name)
unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id) extruder_stack.setName(extruder_definition.getName())
extruder_stack.setDefinition(extruder_definition)
extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
extruder_stack.setNextStack(machine)
extruder_stack = ExtruderStack.ExtruderStack(unique_name) # create empty user changes container otherwise
extruder_stack.setName(extruder_definition.getName()) user_container = InstanceContainer(extruder_stack.id + "_user")
extruder_stack.setDefinition(extruder_definition) user_container.addMetaDataEntry("type", "user")
extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) user_container.addMetaDataEntry("machine", extruder_stack.getId())
extruder_stack.setNextStack(machine) from cura.CuraApplication import CuraApplication
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
user_container.setDefinition(extruder_definition)
# create empty user changes container otherwise if machine.userChanges:
user_container = InstanceContainer(extruder_stack.id + "_user") # for the newly created extruder stack, we need to move all "per-extruder" settings to the user changes
user_container.addMetaDataEntry("type", "user") # container to the extruder stack.
user_container.addMetaDataEntry("machine", extruder_stack.getId()) for user_setting_key in machine.userChanges.getAllKeys():
from cura.CuraApplication import CuraApplication settable_per_extruder = machine.getProperty(user_setting_key, "settable_per_extruder")
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) if settable_per_extruder:
user_container.setDefinition(extruder_definition) user_container.addInstance(machine.userChanges.getInstance(user_setting_key))
machine.userChanges.removeInstance(user_setting_key, postpone_emit = True)
if machine.userChanges: extruder_stack.setUserChanges(user_container)
# for the newly created extruder stack, we need to move all "per-extruder" settings to the user changes self.addContainer(user_container)
# container to the extruder stack.
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))
machine.userChanges.removeInstance(user_setting_key, postpone_emit = True)
extruder_stack.setUserChanges(user_container) variant_id = "default"
self.addContainer(user_container) if machine.variant.getId() not in ("empty", "empty_variant"):
variant_id = machine.variant.getId()
else:
variant_id = "empty_variant"
extruder_stack.setVariantById(variant_id)
variant_id = "default" material_id = "default"
if machine.variant.getId() not in ("empty", "empty_variant"): if machine.material.getId() not in ("empty", "empty_material"):
variant_id = machine.variant.getId() material_id = machine.material.getId()
else:
material_id = "empty_material"
extruder_stack.setMaterialById(material_id)
quality_id = "default"
if machine.quality.getId() not in ("empty", "empty_quality"):
quality_id = machine.quality.getId()
else:
quality_id = "empty_quality"
extruder_stack.setQualityById(quality_id)
if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"):
extruder_quality_changes_container = self.findInstanceContainers(name = machine.qualityChanges.getName(), extruder = extruder_id)
if extruder_quality_changes_container:
extruder_quality_changes_container = extruder_quality_changes_container[0]
quality_changes_id = extruder_quality_changes_container.getId()
extruder_stack.setQualityChangesById(quality_changes_id)
else: else:
variant_id = "empty_variant" # Some extruder quality_changes containers can be created at runtime as files in the qualities
extruder_stack.setVariantById(variant_id) # folder. Those files won't be loaded in the registry immediately. So we also need to search
# the folder to see if the quality_changes exists.
material_id = "default" extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName())
if machine.material.getId() not in ("empty", "empty_material"):
material_id = machine.material.getId()
else:
material_id = "empty_material"
extruder_stack.setMaterialById(material_id)
quality_id = "default"
if machine.quality.getId() not in ("empty", "empty_quality"):
quality_id = machine.quality.getId()
else:
quality_id = "empty_quality"
extruder_stack.setQualityById(quality_id)
if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"):
extruder_quality_changes_container = self.findInstanceContainers(name = machine.qualityChanges.getName(), extruder = extruder_id)
if extruder_quality_changes_container: if extruder_quality_changes_container:
extruder_quality_changes_container = extruder_quality_changes_container[0]
quality_changes_id = extruder_quality_changes_container.getId() quality_changes_id = extruder_quality_changes_container.getId()
extruder_stack.setQualityChangesById(quality_changes_id) extruder_stack.setQualityChangesById(quality_changes_id)
else:
# Some extruder quality_changes containers can be created at runtime as files in the qualities
# folder. Those files won't be loaded in the registry immediately. So we also need to search
# the folder to see if the quality_changes exists.
extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName())
if extruder_quality_changes_container:
quality_changes_id = extruder_quality_changes_container.getId()
extruder_stack.setQualityChangesById(quality_changes_id)
if not extruder_quality_changes_container: if not extruder_quality_changes_container:
Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]", Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]",
machine.qualityChanges.getName(), extruder_stack.getId()) machine.qualityChanges.getName(), extruder_stack.getId())
else:
extruder_stack.setQualityChangesById("empty_quality_changes")
self.addContainer(extruder_stack) self.addContainer(extruder_stack)
return extruder_stack return extruder_stack

View file

@ -760,7 +760,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if not extruder_stacks: if not extruder_stacks:
stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder") stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder")
if stack: if stack:
extruder_stacks.append(stack) if self._resolve_strategies["machine"] == "override":
# in case the extruder is newly created (for a single-extrusion machine), we need to override
# the existing extruder stack.
existing_extruder_stack = global_stack.extruders[stack.getMetaDataEntry("position")]
for idx in range(len(_ContainerIndexes.IndexTypeMap)):
existing_extruder_stack.replaceContainer(idx, stack._containers[idx], postpone_emit = True)
extruder_stacks.append(existing_extruder_stack)
else:
extruder_stacks.append(stack)
except: except:
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.") Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
@ -812,6 +820,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
available_quality_types = [q.getMetaDataEntry("quality_type") for q in available_quality] available_quality_types = [q.getMetaDataEntry("quality_type") for q in available_quality]
if global_stack.quality.getMetaDataEntry("quality_type") not in available_quality_types: if global_stack.quality.getMetaDataEntry("quality_type") not in available_quality_types:
# We are here because the quality_type specified in the project is not supported any more,
# so we need to switch it to the "preferred quality" if present, otherwise "normal".
quality_has_been_changed = True quality_has_been_changed = True
# find the preferred quality # find the preferred quality
@ -845,6 +855,41 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
else: else:
# we cannot find the preferred quality. THIS SHOULD NOT HAPPEN # we cannot find the preferred quality. THIS SHOULD NOT HAPPEN
Logger.log("e", "Cannot find the preferred quality for machine [%s]", global_stack.getId()) Logger.log("e", "Cannot find the preferred quality for machine [%s]", global_stack.getId())
else:
# The quality_type specified in the project file is usable, but the quality container itself may not
# be correct. For example, for UM2, the quality container can be "draft" while it should be "um2_draft"
# instead.
# In this code branch, we try to fix those incorrect quality containers.
search_criteria = {"type": "quality",
"quality_type": global_stack.quality.getMetaDataEntry("quality_type")}
search_criteria["definition"] = global_stack.definition.getId()
if not parseBool(global_stack.getMetaDataEntry("has_machine_quality", "False")):
search_criteria["definition"] = "fdmprinter"
containers = self._container_registry.findInstanceContainers(**search_criteria)
containers = [c for c in containers if not c.getMetaDataEntry("material", "")]
if not containers:
# cannot find machine-specific qualities, so just use fdmprinter to search again
search_criteria["definition"] = "fdmprinter"
containers = self._container_registry.findInstanceContainers(**search_criteria)
containers = [c for c in containers if not c.getMetaDataEntry("material", "")]
if containers:
new_quality_container = containers[0]
global_stack.quality = new_quality_container
for extruder_stack in extruder_stacks:
search_criteria = {"type": "quality",
"quality_type": global_stack.quality.getMetaDataEntry("quality_type")}
search_criteria["definition"] = global_stack.definition.getId()
if not parseBool(global_stack.getMetaDataEntry("has_machine_quality", "False")):
search_criteria["definition"] = "fdmprinter"
if global_stack.getMetaDataEntry("has_machine_materials") and extruder_stack.material.getId() not in ("empty", "empty_material"):
search_criteria["material"] = extruder_stack.material.getId()
containers = self._container_registry.findInstanceContainers(**search_criteria)
if containers:
extruder_stack.quality = containers[0]
# Replacing the old containers if resolve is "new". # Replacing the old containers if resolve is "new".
# When resolve is "new", some containers will get renamed, so all the other containers that reference to those # When resolve is "new", some containers will get renamed, so all the other containers that reference to those