Import profiles for the current machine

Takes into consideration printers that use quality-profiles from other printers, while gracefully handling mismatches in the number of extruders

Fixes CURA-2500, contributes to CURA-2478
This commit is contained in:
fieldOfView 2016-10-03 15:29:25 +02:00
parent 5d1b77c551
commit 2f57d0fb6e
2 changed files with 55 additions and 10 deletions

View file

@ -678,6 +678,16 @@ class ContainerManager(QObject):
duplicated_container.setDirty(True) duplicated_container.setDirty(True)
self._container_registry.addContainer(duplicated_container) 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 # Factory function, used by QML
@staticmethod @staticmethod
def createContainerManager(engine, js_engine): def createContainerManager(engine, js_engine):

View file

@ -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.PluginRegistry import PluginRegistry #For getting the possible profile writers to write with.
from UM.Util import parseBool from UM.Util import parseBool
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ContainerManager import ContainerManager
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
@ -128,8 +131,14 @@ 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")} 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() plugin_registry = PluginRegistry.getInstance()
container_registry = ContainerRegistry.getInstance()
extension = file_name.split(".")[-1] 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()))
for plugin_id, meta_data in self._getIOPlugins("profile_reader"): for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
if meta_data["profile_reader"][0]["extension"] != extension: if meta_data["profile_reader"][0]["extension"] != extension:
continue continue
@ -148,13 +157,35 @@ class CuraContainerRegistry(ContainerRegistry):
self._configureProfile(profile, name_seed) self._configureProfile(profile, name_seed)
return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) } return { "status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile.getName()) }
else: else:
profile_index = -1
global_profile = None
for profile in profile_or_list: for profile in profile_or_list:
extruder_id = profile.getMetaDataEntry("extruder") if profile_index >= 0:
if extruder_id: if len(machine_extruders) > profile_index:
profile_name = "%s_%s" % (extruder_id, name_seed) 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)
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())
continue
else:
# The imported composite profile has a profile for an extruder that this machine does not have. Ignore this extruder-profile
continue
else: else:
global_profile = profile
profile_name = name_seed 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 profile.setDirty(True) # Ensure the profiles are correctly saved
if "type" in profile.getMetaData(): if "type" in profile.getMetaData():
profile.setMetaDataEntry("type", "quality_changes") profile.setMetaDataEntry("type", "quality_changes")
@ -163,6 +194,8 @@ class CuraContainerRegistry(ContainerRegistry):
self._configureProfile(profile, profile_name) self._configureProfile(profile, profile_name)
profile.setName(new_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())} 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. # If it hasn't returned by now, none of the plugins loaded the profile successfully.
@ -175,7 +208,7 @@ class CuraContainerRegistry(ContainerRegistry):
profile._id = new_id profile._id = new_id
if self._machineHasOwnQualities(): if self._machineHasOwnQualities():
profile.setDefinition(self._activeDefinition()) profile.setDefinition(self._activeQualityDefinition())
if self._machineHasOwnMaterials(): if self._machineHasOwnMaterials():
profile.addMetaDataEntry("material", self._activeMaterialId()) profile.addMetaDataEntry("material", self._activeMaterialId())
else: else:
@ -196,12 +229,14 @@ class CuraContainerRegistry(ContainerRegistry):
result.append( (plugin_id, meta_data) ) result.append( (plugin_id, meta_data) )
return result return result
## Gets the active definition ## Get the definition to use to select quality profiles for the active machine
# \return the active definition object or None if there is no definition # \return the active quality definition object or None if there is no quality definition
def _activeDefinition(self): def _activeQualityDefinition(self):
global_container_stack = Application.getInstance().getGlobalContainerStack() global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack: 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: if definition:
return definition return definition
return None return None