def _performMerge(self, merge_into: InstanceContainer, merge: InstanceContainer, clear_settings: bool = True) -> None: if merge == merge_into: return '''isSolubile=False for key in merge.getAllKeys(): if(key=="support_solubile"): print("supporto solubile:=") print(merge.getProperty(key, "value")) if(merge.getProperty(key,"value")==True):#solubile enable isSolubile=True print("SOLUBILE?"+str(isSolubile)) ''' #remerge and set Property for key in merge.getAllKeys(): #if(key == "support_bottom_distance" or key == "support_top_distance"): #if(isSolubile): # merge_into.setProperty(key, "value","0.0") # print("SETTED OFFSET 0") #else: merge_into.setProperty(key, "value", merge.getProperty(key, "value")) if clear_settings: #print("CLEAR SETTINGS") merge.clear()
def _performMerge(self, merge_into: InstanceContainer, merge: InstanceContainer, clear_settings: bool = True) -> None: if merge == merge_into: return for key in merge.getAllKeys(): merge_into.setProperty(key, "value", merge.getProperty(key, "value")) if clear_settings: merge.clear()
def addExtruderStackForSingleExtrusionMachine( self, machine, extruder_id, new_global_quality_changes=None, create_new_ids=True): new_extruder_id = extruder_id application = cura.CuraApplication.CuraApplication.getInstance() 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] unique_name = self.uniqueName( machine.getName() + " " + new_extruder_id ) if create_new_ids else machine.getName() + " " + new_extruder_id extruder_stack = ExtruderStack.ExtruderStack(unique_name) extruder_stack.setName(extruder_definition.getName()) extruder_stack.setDefinition(extruder_definition) extruder_stack.setMetaDataEntry( "position", extruder_definition.getMetaDataEntry("position")) # create a new definition_changes container for the extruder stack definition_changes_id = self.uniqueName( extruder_stack.getId() + "_settings" ) if create_new_ids else extruder_stack.getId() + "_settings" definition_changes_name = definition_changes_id definition_changes = InstanceContainer(definition_changes_id, parent=application) definition_changes.setName(definition_changes_name) definition_changes.setMetaDataEntry("setting_version", application.SettingVersion) definition_changes.setMetaDataEntry("type", "definition_changes") definition_changes.setMetaDataEntry("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_id = self.uniqueName( extruder_stack.getId() + "_user") if create_new_ids else extruder_stack.getId() + "_user" user_container_name = user_container_id user_container = InstanceContainer(user_container_id, parent=application) user_container.setName(user_container_name) user_container.setMetaDataEntry("type", "user") user_container.setMetaDataEntry("machine", machine.getId()) user_container.setMetaDataEntry("setting_version", application.SettingVersion) user_container.setDefinition(machine.definition.getId()) user_container.setMetaDataEntry( "position", extruder_stack.getMetaDataEntry("position")) if machine.userChanges: # For the newly created extruder stack, we need to move all "per-extruder" settings to the user changes # 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: 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) extruder_stack.setUserChanges(user_container) empty_variant = application.empty_variant_container empty_material = application.empty_material_container empty_quality = application.empty_quality_container if machine.variant.getId() not in ("empty", "empty_variant"): variant = machine.variant else: variant = empty_variant extruder_stack.variant = variant if machine.material.getId() not in ("empty", "empty_material"): material = machine.material else: material = empty_material extruder_stack.material = material if machine.quality.getId() not in ("empty", "empty_quality"): quality = machine.quality else: quality = empty_quality extruder_stack.quality = quality machine_quality_changes = machine.qualityChanges if new_global_quality_changes is not None: machine_quality_changes = new_global_quality_changes if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"): extruder_quality_changes_container = self.findInstanceContainers( name=machine_quality_changes.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.qualityChanges = self.findInstanceContainers( id=quality_changes_id)[0] 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_quality_changes.getName()) if extruder_quality_changes_container: quality_changes_id = extruder_quality_changes_container.getId( ) extruder_quality_changes_container.setMetaDataEntry( "position", extruder_definition.getMetaDataEntry("position")) extruder_stack.qualityChanges = self.findInstanceContainers( id=quality_changes_id)[0] else: # If we still cannot find a quality changes container for the extruder, create a new one container_name = machine_quality_changes.getName() container_id = self.uniqueName(extruder_stack.getId() + "_qc_" + container_name) extruder_quality_changes_container = InstanceContainer( container_id, parent=application) extruder_quality_changes_container.setName(container_name) extruder_quality_changes_container.setMetaDataEntry( "type", "quality_changes") extruder_quality_changes_container.setMetaDataEntry( "setting_version", application.SettingVersion) extruder_quality_changes_container.setMetaDataEntry( "position", extruder_definition.getMetaDataEntry("position")) extruder_quality_changes_container.setMetaDataEntry( "quality_type", machine_quality_changes.getMetaDataEntry( "quality_type")) extruder_quality_changes_container.setDefinition( machine_quality_changes.getDefinition().getId()) self.addContainer(extruder_quality_changes_container) extruder_stack.qualityChanges = extruder_quality_changes_container if not extruder_quality_changes_container: Logger.log( "w", "Could not find quality_changes named [%s] for extruder [%s]", machine_quality_changes.getName(), extruder_stack.getId()) else: # Move all per-extruder settings to the extruder's quality changes for qc_setting_key in machine_quality_changes.getAllKeys(): settable_per_extruder = machine.getProperty( qc_setting_key, "settable_per_extruder") if settable_per_extruder: setting_value = machine_quality_changes.getProperty( qc_setting_key, "value") setting_definition = machine.getSettingDefinition( qc_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. extruder_quality_changes_container.addInstance( new_instance) extruder_quality_changes_container.setDirty(True) machine_quality_changes.removeInstance( qc_setting_key, postpone_emit=True) else: extruder_stack.qualityChanges = self.findInstanceContainers( id="empty_quality_changes")[0] self.addContainer(extruder_stack) # Also need to fix the other qualities that are suitable for this machine. Those quality changes may still have # per-extruder settings in the container for the machine instead of the extruder. if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"): quality_changes_machine_definition_id = machine_quality_changes.getDefinition( ).getId() else: whole_machine_definition = machine.definition machine_entry = machine.definition.getMetaDataEntry("machine") if machine_entry is not None: container_registry = ContainerRegistry.getInstance() whole_machine_definition = container_registry.findDefinitionContainers( id=machine_entry)[0] quality_changes_machine_definition_id = "fdmprinter" if whole_machine_definition.getMetaDataEntry( "has_machine_quality"): quality_changes_machine_definition_id = machine.definition.getMetaDataEntry( "quality_definition", whole_machine_definition.getId()) qcs = self.findInstanceContainers( type="quality_changes", definition=quality_changes_machine_definition_id) qc_groups = {} # map of qc names -> qc containers for qc in qcs: qc_name = qc.getName() if qc_name not in qc_groups: qc_groups[qc_name] = [] qc_groups[qc_name].append(qc) # Try to find from the quality changes cura directory too quality_changes_container = self._findQualityChangesContainerInCuraFolder( machine_quality_changes.getName()) if quality_changes_container: qc_groups[qc_name].append(quality_changes_container) for qc_name, qc_list in qc_groups.items(): qc_dict = {"global": None, "extruders": []} for qc in qc_list: extruder_position = qc.getMetaDataEntry("position") if extruder_position is not None: qc_dict["extruders"].append(qc) else: qc_dict["global"] = qc if qc_dict["global"] is not None and len( qc_dict["extruders"]) == 1: # Move per-extruder settings for qc_setting_key in qc_dict["global"].getAllKeys(): settable_per_extruder = machine.getProperty( qc_setting_key, "settable_per_extruder") if settable_per_extruder: setting_value = qc_dict["global"].getProperty( qc_setting_key, "value") setting_definition = machine.getSettingDefinition( qc_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. qc_dict["extruders"][0].addInstance(new_instance) qc_dict["extruders"][0].setDirty(True) qc_dict["global"].removeInstance(qc_setting_key, postpone_emit=True) # Set next stack at the end extruder_stack.setNextStack(machine) return extruder_stack
def read(self, file_name): if file_name.split(".")[-1] != "ini": return None global_container_stack = Application.getInstance().getGlobalContainerStack() if not global_container_stack: return None multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 if multi_extrusion: Logger.log("e", "Unable to import legacy profile %s. Multi extrusion is not supported", file_name) raise Exception("Unable to import legacy profile. Multi extrusion is not supported") Logger.log("i", "Importing legacy profile from file " + file_name + ".") profile = InstanceContainer("Imported Legacy Profile") # Create an empty profile. parser = configparser.ConfigParser(interpolation = None) try: with open(file_name) as f: parser.readfp(f) # Parse the INI file. except Exception as e: Logger.log("e", "Unable to open legacy profile %s: %s", file_name, str(e)) return None # Legacy Cura saved the profile under the section "profile_N" where N is the ID of a machine, except when you export in which case it saves it in the section "profile". # Since importing multiple machine profiles is out of scope, just import the first section we find. section = "" for found_section in parser.sections(): if found_section.startswith("profile"): section = found_section break if not section: # No section starting with "profile" was found. Probably not a proper INI file. return None try: with open(os.path.join(PluginRegistry.getInstance().getPluginPath("LegacyProfileReader"), "DictionaryOfDoom.json"), "r", -1, "utf-8") as f: dict_of_doom = json.load(f) # Parse the Dictionary of Doom. except IOError as e: Logger.log("e", "Could not open DictionaryOfDoom.json for reading: %s", str(e)) return None except Exception as e: Logger.log("e", "Could not parse DictionaryOfDoom.json: %s", str(e)) return None defaults = self.prepareDefaults(dict_of_doom) legacy_settings = self.prepareLocals(parser, section, defaults) #Gets the settings from the legacy profile. #Check the target version in the Dictionary of Doom with this application version. if "target_version" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no target version. Is it the correct JSON file?") return None if InstanceContainer.Version != dict_of_doom["target_version"]: Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version)) return None if "translation" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?") return None current_printer_definition = global_container_stack.getBottom() profile.setDefinition(current_printer_definition) for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] compiled = compile(old_setting_expression, new_setting, "eval") try: new_value = eval(compiled, {"math": math}, legacy_settings) # Pass the legacy settings as local variables to allow access to in the evaluation. value_using_defaults = eval(compiled, {"math": math}, defaults) #Evaluate again using only the default values to try to see if they are default. except Exception: # Probably some setting name that was missing or something else that went wrong in the ini file. Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.") continue definitions = current_printer_definition.findDefinitions(key = new_setting) if definitions: if new_value != value_using_defaults and definitions[0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setProperty(new_setting, "value", new_value) # Store the setting in the profile! if len(profile.getAllKeys()) == 0: Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") profile.setDirty(True) profile.addMetaDataEntry("type", "quality_changes") profile.addMetaDataEntry("quality_type", "normal") return profile
def read(self, file_name): if file_name.split(".")[-1] != "ini": return None global_container_stack = Application.getInstance( ).getGlobalContainerStack() if not global_container_stack: return None multi_extrusion = global_container_stack.getProperty( "machine_extruder_count", "value") > 1 if multi_extrusion: Logger.log( "e", "Unable to import legacy profile %s. Multi extrusion is not supported", file_name) raise Exception( "Unable to import legacy profile. Multi extrusion is not supported" ) Logger.log("i", "Importing legacy profile from file " + file_name + ".") profile = InstanceContainer( "Imported Legacy Profile") # Create an empty profile. parser = configparser.ConfigParser(interpolation=None) try: with open(file_name) as f: parser.readfp(f) #Parse the INI file. except Exception as e: Logger.log("e", "Unable to open legacy profile %s: %s", file_name, str(e)) return None #Legacy Cura saved the profile under the section "profile_N" where N is the ID of a machine, except when you export in which case it saves it in the section "profile". #Since importing multiple machine profiles is out of scope, just import the first section we find. section = "" for found_section in parser.sections(): if found_section.startswith("profile"): section = found_section break if not section: #No section starting with "profile" was found. Probably not a proper INI file. return None try: with open( os.path.join( PluginRegistry.getInstance().getPluginPath( "LegacyProfileReader"), "DictionaryOfDoom.json"), "r", -1, "utf-8") as f: dict_of_doom = json.load(f) #Parse the Dictionary of Doom. except IOError as e: Logger.log("e", "Could not open DictionaryOfDoom.json for reading: %s", str(e)) return None except Exception as e: Logger.log("e", "Could not parse DictionaryOfDoom.json: %s", str(e)) return None defaults = self.prepareDefaults(dict_of_doom) legacy_settings = self.prepareLocals( parser, section, defaults) #Gets the settings from the legacy profile. #Check the target version in the Dictionary of Doom with this application version. if "target_version" not in dict_of_doom: Logger.log( "e", "Dictionary of Doom has no target version. Is it the correct JSON file?" ) return None if InstanceContainer.Version != dict_of_doom["target_version"]: Logger.log( "e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version)) return None if "translation" not in dict_of_doom: Logger.log( "e", "Dictionary of Doom has no translation. Is it the correct JSON file?" ) return None current_printer_definition = global_container_stack.getBottom() profile.setDefinition(current_printer_definition) for new_setting in dict_of_doom[ "translation"]: #Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] compiled = compile(old_setting_expression, new_setting, "eval") try: new_value = eval( compiled, {"math": math}, legacy_settings ) #Pass the legacy settings as local variables to allow access to in the evaluation. value_using_defaults = eval( compiled, {"math": math}, defaults ) #Evaluate again using only the default values to try to see if they are default. except Exception: #Probably some setting name that was missing or something else that went wrong in the ini file. Logger.log( "w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile." ) continue definitions = current_printer_definition.findDefinitions( key=new_setting) if definitions: if new_value != value_using_defaults and definitions[ 0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setProperty( new_setting, "value", new_value) # Store the setting in the profile! if len(profile.getAllKeys()) == 0: Logger.log( "i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile." ) profile.setDirty(True) profile.addMetaDataEntry("type", "quality_changes") profile.addMetaDataEntry("quality_type", "normal") return profile
def read(self, file_name): if file_name.split(".")[-1] != "ini": return None global_container_stack = Application.getInstance( ).getGlobalContainerStack() if not global_container_stack: return None multi_extrusion = global_container_stack.getProperty( "machine_extruder_count", "value") > 1 if multi_extrusion: Logger.log( "e", "Unable to import legacy profile %s. Multi extrusion is not supported", file_name) raise Exception( "Unable to import legacy profile. Multi extrusion is not supported" ) Logger.log("i", "Importing legacy profile from file " + file_name + ".") container_registry = ContainerRegistry.getInstance() profile_id = container_registry.uniqueName("Imported Legacy Profile") profile = InstanceContainer(profile_id) # Create an empty profile. parser = configparser.ConfigParser(interpolation=None) try: parser.read([file_name]) # Parse the INI file. except Exception as e: Logger.log("e", "Unable to open legacy profile %s: %s", file_name, str(e)) return None # Legacy Cura saved the profile under the section "profile_N" where N is the ID of a machine, except when you export in which case it saves it in the section "profile". # Since importing multiple machine profiles is out of scope, just import the first section we find. section = "" for found_section in parser.sections(): if found_section.startswith("profile"): section = found_section break if not section: # No section starting with "profile" was found. Probably not a proper INI file. return None try: with open( os.path.join( PluginRegistry.getInstance().getPluginPath( "LegacyProfileReader"), "DictionaryOfDoom.json"), "r", -1, "utf-8") as f: dict_of_doom = json.load(f) # Parse the Dictionary of Doom. except IOError as e: Logger.log("e", "Could not open DictionaryOfDoom.json for reading: %s", str(e)) return None except Exception as e: Logger.log("e", "Could not parse DictionaryOfDoom.json: %s", str(e)) return None defaults = self.prepareDefaults(dict_of_doom) legacy_settings = self.prepareLocals( parser, section, defaults) #Gets the settings from the legacy profile. #Check the target version in the Dictionary of Doom with this application version. if "target_version" not in dict_of_doom: Logger.log( "e", "Dictionary of Doom has no target version. Is it the correct JSON file?" ) return None if InstanceContainer.Version != dict_of_doom["target_version"]: Logger.log( "e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version)) return None if "translation" not in dict_of_doom: Logger.log( "e", "Dictionary of Doom has no translation. Is it the correct JSON file?" ) return None current_printer_definition = global_container_stack.definition profile.setDefinition(current_printer_definition.getId()) for new_setting in dict_of_doom[ "translation"]: # Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] compiled = compile(old_setting_expression, new_setting, "eval") try: new_value = eval( compiled, {"math": math}, legacy_settings ) # Pass the legacy settings as local variables to allow access to in the evaluation. value_using_defaults = eval( compiled, {"math": math}, defaults ) #Evaluate again using only the default values to try to see if they are default. except Exception: # Probably some setting name that was missing or something else that went wrong in the ini file. Logger.log( "w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile." ) continue definitions = current_printer_definition.findDefinitions( key=new_setting) if definitions: if new_value != value_using_defaults and definitions[ 0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setProperty( new_setting, "value", new_value) # Store the setting in the profile! if len(profile.getAllKeys()) == 0: Logger.log( "i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile." ) profile.addMetaDataEntry("type", "profile") # don't know what quality_type it is based on, so use "normal" by default profile.addMetaDataEntry("quality_type", "normal") profile.setName(profile_id) profile.setDirty(True) #Serialise and deserialise in order to perform the version upgrade. parser = configparser.ConfigParser(interpolation=None) data = profile.serialize() parser.read_string(data) parser["general"]["version"] = "1" if parser.has_section("values"): parser["settings"] = parser["values"] del parser["values"] stream = io.StringIO() parser.write(stream) data = stream.getvalue() profile.deserialize(data) #We need to return one extruder stack and one global stack. global_container_id = container_registry.uniqueName( "Global Imported Legacy Profile") global_profile = profile.duplicate( new_id=global_container_id, new_name=profile_id ) #Needs to have the same name as the extruder profile. global_profile.setDirty(True) #Only the extruder stack has an extruder metadata entry. profile.addMetaDataEntry( "extruder", ExtruderManager.getInstance().getActiveExtruderStack().definition. getId()) #Split all settings into per-extruder and global settings. for setting_key in profile.getAllKeys(): settable_per_extruder = global_container_stack.getProperty( setting_key, "settable_per_extruder") if settable_per_extruder: global_profile.removeInstance(setting_key) else: profile.removeInstance(setting_key) return [global_profile, profile]
def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id, new_global_quality_changes = None, create_new_ids = True): new_extruder_id = extruder_id application = CuraApplication.getInstance() 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] unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id) if create_new_ids else machine.getName() + " " + new_extruder_id extruder_stack = ExtruderStack.ExtruderStack(unique_name) extruder_stack.setName(extruder_definition.getName()) extruder_stack.setDefinition(extruder_definition) extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) # create a new definition_changes container for the extruder stack definition_changes_id = self.uniqueName(extruder_stack.getId() + "_settings") if create_new_ids else extruder_stack.getId() + "_settings" definition_changes_name = definition_changes_id definition_changes = InstanceContainer(definition_changes_id, parent = application) 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_id = self.uniqueName(extruder_stack.getId() + "_user") if create_new_ids else extruder_stack.getId() + "_user" user_container_name = user_container_id user_container = InstanceContainer(user_container_id, parent = application) user_container.setName(user_container_name) user_container.addMetaDataEntry("type", "user") user_container.addMetaDataEntry("machine", machine.getId()) user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) user_container.setDefinition(machine.definition.getId()) user_container.setMetaDataEntry("position", extruder_stack.getMetaDataEntry("position")) if machine.userChanges: # for the newly created extruder stack, we need to move all "per-extruder" settings to the user changes # 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: 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) extruder_stack.setUserChanges(user_container) empty_variant = application.empty_variant_container empty_material = application.empty_material_container empty_quality = application.empty_quality_container if machine.variant.getId() not in ("empty", "empty_variant"): variant = machine.variant else: variant = empty_variant extruder_stack.variant = variant if machine.material.getId() not in ("empty", "empty_material"): material = machine.material else: material = empty_material extruder_stack.material = material if machine.quality.getId() not in ("empty", "empty_quality"): quality = machine.quality else: quality = empty_quality extruder_stack.quality = quality machine_quality_changes = machine.qualityChanges if new_global_quality_changes is not None: machine_quality_changes = new_global_quality_changes if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"): extruder_quality_changes_container = self.findInstanceContainers(name = machine_quality_changes.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.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0] 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_quality_changes.getName()) if extruder_quality_changes_container: quality_changes_id = extruder_quality_changes_container.getId() extruder_quality_changes_container.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) extruder_stack.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0] else: # if we still cannot find a quality changes container for the extruder, create a new one container_name = machine_quality_changes.getName() container_id = self.uniqueName(extruder_stack.getId() + "_qc_" + container_name) extruder_quality_changes_container = InstanceContainer(container_id, parent = application) extruder_quality_changes_container.setName(container_name) extruder_quality_changes_container.addMetaDataEntry("type", "quality_changes") extruder_quality_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) extruder_quality_changes_container.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) extruder_quality_changes_container.addMetaDataEntry("quality_type", machine_quality_changes.getMetaDataEntry("quality_type")) extruder_quality_changes_container.setDefinition(machine_quality_changes.getDefinition().getId()) self.addContainer(extruder_quality_changes_container) extruder_stack.qualityChanges = extruder_quality_changes_container if not extruder_quality_changes_container: Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]", machine_quality_changes.getName(), extruder_stack.getId()) else: # move all per-extruder settings to the extruder's quality changes for qc_setting_key in machine_quality_changes.getAllKeys(): settable_per_extruder = machine.getProperty(qc_setting_key, "settable_per_extruder") if settable_per_extruder: setting_value = machine_quality_changes.getProperty(qc_setting_key, "value") setting_definition = machine.getSettingDefinition(qc_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. extruder_quality_changes_container.addInstance(new_instance) extruder_quality_changes_container.setDirty(True) machine_quality_changes.removeInstance(qc_setting_key, postpone_emit=True) else: extruder_stack.qualityChanges = self.findInstanceContainers(id = "empty_quality_changes")[0] self.addContainer(extruder_stack) # Also need to fix the other qualities that are suitable for this machine. Those quality changes may still have # per-extruder settings in the container for the machine instead of the extruder. if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"): quality_changes_machine_definition_id = machine_quality_changes.getDefinition().getId() else: whole_machine_definition = machine.definition machine_entry = machine.definition.getMetaDataEntry("machine") if machine_entry is not None: container_registry = ContainerRegistry.getInstance() whole_machine_definition = container_registry.findDefinitionContainers(id = machine_entry)[0] quality_changes_machine_definition_id = "fdmprinter" if whole_machine_definition.getMetaDataEntry("has_machine_quality"): quality_changes_machine_definition_id = machine.definition.getMetaDataEntry("quality_definition", whole_machine_definition.getId()) qcs = self.findInstanceContainers(type = "quality_changes", definition = quality_changes_machine_definition_id) qc_groups = {} # map of qc names -> qc containers for qc in qcs: qc_name = qc.getName() if qc_name not in qc_groups: qc_groups[qc_name] = [] qc_groups[qc_name].append(qc) # try to find from the quality changes cura directory too quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine_quality_changes.getName()) if quality_changes_container: qc_groups[qc_name].append(quality_changes_container) for qc_name, qc_list in qc_groups.items(): qc_dict = {"global": None, "extruders": []} for qc in qc_list: extruder_position = qc.getMetaDataEntry("position") if extruder_position is not None: qc_dict["extruders"].append(qc) else: qc_dict["global"] = qc if qc_dict["global"] is not None and len(qc_dict["extruders"]) == 1: # move per-extruder settings for qc_setting_key in qc_dict["global"].getAllKeys(): settable_per_extruder = machine.getProperty(qc_setting_key, "settable_per_extruder") if settable_per_extruder: setting_value = qc_dict["global"].getProperty(qc_setting_key, "value") setting_definition = machine.getSettingDefinition(qc_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. qc_dict["extruders"][0].addInstance(new_instance) qc_dict["extruders"][0].setDirty(True) qc_dict["global"].removeInstance(qc_setting_key, postpone_emit=True) # Set next stack at the end extruder_stack.setNextStack(machine) return extruder_stack
def read(self, file_name): if file_name.split(".")[-1] != "ini": return None global_container_stack = Application.getInstance().getGlobalContainerStack() if not global_container_stack: return None multi_extrusion = global_container_stack.getProperty("machine_extruder_count", "value") > 1 if multi_extrusion: Logger.log("e", "Unable to import legacy profile %s. Multi extrusion is not supported", file_name) raise Exception("Unable to import legacy profile. Multi extrusion is not supported") Logger.log("i", "Importing legacy profile from file " + file_name + ".") container_registry = ContainerRegistry.getInstance() profile_id = container_registry.uniqueName("Imported Legacy Profile") profile = InstanceContainer(profile_id) # Create an empty profile. parser = configparser.ConfigParser(interpolation = None) try: parser.read([file_name]) # Parse the INI file. except Exception as e: Logger.log("e", "Unable to open legacy profile %s: %s", file_name, str(e)) return None # Legacy Cura saved the profile under the section "profile_N" where N is the ID of a machine, except when you export in which case it saves it in the section "profile". # Since importing multiple machine profiles is out of scope, just import the first section we find. section = "" for found_section in parser.sections(): if found_section.startswith("profile"): section = found_section break if not section: # No section starting with "profile" was found. Probably not a proper INI file. return None try: with open(os.path.join(PluginRegistry.getInstance().getPluginPath("LegacyProfileReader"), "DictionaryOfDoom.json"), "r", encoding = "utf-8") as f: dict_of_doom = json.load(f) # Parse the Dictionary of Doom. except IOError as e: Logger.log("e", "Could not open DictionaryOfDoom.json for reading: %s", str(e)) return None except Exception as e: Logger.log("e", "Could not parse DictionaryOfDoom.json: %s", str(e)) return None defaults = self.prepareDefaults(dict_of_doom) legacy_settings = self.prepareLocals(parser, section, defaults) #Gets the settings from the legacy profile. #Check the target version in the Dictionary of Doom with this application version. if "target_version" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no target version. Is it the correct JSON file?") return None if InstanceContainer.Version != dict_of_doom["target_version"]: Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version)) return None if "translation" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?") return None current_printer_definition = global_container_stack.definition quality_definition = current_printer_definition.getMetaDataEntry("quality_definition") if not quality_definition: quality_definition = current_printer_definition.getId() profile.setDefinition(quality_definition) for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] compiled = compile(old_setting_expression, new_setting, "eval") try: new_value = eval(compiled, {"math": math}, legacy_settings) # Pass the legacy settings as local variables to allow access to in the evaluation. value_using_defaults = eval(compiled, {"math": math}, defaults) #Evaluate again using only the default values to try to see if they are default. except Exception: # Probably some setting name that was missing or something else that went wrong in the ini file. Logger.log("w", "Setting " + new_setting + " could not be set because the evaluation failed. Something is probably missing from the imported legacy profile.") continue definitions = current_printer_definition.findDefinitions(key = new_setting) if definitions: if new_value != value_using_defaults and definitions[0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura. profile.setProperty(new_setting, "value", new_value) # Store the setting in the profile! if len(profile.getAllKeys()) == 0: Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") profile.addMetaDataEntry("type", "profile") # don't know what quality_type it is based on, so use "normal" by default profile.addMetaDataEntry("quality_type", "normal") profile.setName(profile_id) profile.setDirty(True) #Serialise and deserialise in order to perform the version upgrade. parser = configparser.ConfigParser(interpolation=None) data = profile.serialize() parser.read_string(data) parser["general"]["version"] = "1" if parser.has_section("values"): parser["settings"] = parser["values"] del parser["values"] stream = io.StringIO() parser.write(stream) data = stream.getvalue() profile.deserialize(data) # The definition can get reset to fdmprinter during the deserialization's upgrade. Here we set the definition # again. profile.setDefinition(quality_definition) #We need to return one extruder stack and one global stack. global_container_id = container_registry.uniqueName("Global Imported Legacy Profile") global_profile = profile.duplicate(new_id = global_container_id, new_name = profile_id) #Needs to have the same name as the extruder profile. global_profile.setDirty(True) profile_definition = "fdmprinter" from UM.Util import parseBool if parseBool(global_container_stack.getMetaDataEntry("has_machine_quality", "False")): profile_definition = global_container_stack.getMetaDataEntry("quality_definition") if not profile_definition: profile_definition = global_container_stack.definition.getId() global_profile.setDefinition(profile_definition) return [global_profile]
def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id): new_extruder_id = 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] unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id) extruder_stack = ExtruderStack.ExtruderStack(unique_name) extruder_stack.setName(extruder_definition.getName()) 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_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()) user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) user_container.setDefinition(machine.definition.getId()) if machine.userChanges: # for the newly created extruder stack, we need to move all "per-extruder" settings to the user changes # 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: 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) extruder_stack.setUserChanges(user_container) variant_id = "default" if machine.variant.getId() not in ("empty", "empty_variant"): variant_id = machine.variant.getId() else: variant_id = "empty_variant" extruder_stack.setVariantById(variant_id) material_id = "default" 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: extruder_quality_changes_container = extruder_quality_changes_container[ 0] quality_changes_id = extruder_quality_changes_container.getId() 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: Logger.log( "w", "Could not find quality_changes named [%s] for extruder [%s]", machine.qualityChanges.getName(), extruder_stack.getId()) else: extruder_stack.setQualityChangesById("empty_quality_changes") self.addContainer(extruder_stack) # Set next stack at the end extruder_stack.setNextStack(machine) return extruder_stack