From e14d78b32abe62ea39543fd6af6c378fdd801ea5 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 13 Dec 2017 10:16:06 +0100 Subject: [PATCH 1/5] Generate more possible machine IDs in XML material profile --- .../XmlMaterialProfile/XmlMaterialProfile.py | 350 ++++++++++-------- 1 file changed, 191 insertions(+), 159 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index c4912826ee..08530f96e2 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -212,11 +212,12 @@ class XmlMaterialProfile(InstanceContainer): for definition_id, container in machine_container_map.items(): definition = container.getDefinition() - try: - product = UM.Dictionary.findKey(product_id_map, definition_id) - except ValueError: - # An unknown product id; export it anyway - product = definition_id + + product = definition_id + for product_name, product_id_list in product_id_map.items(): + if definition_id in product_id_list: + product = product_name + break builder.start("machine") builder.start("machine_identifier", { @@ -530,106 +531,110 @@ class XmlMaterialProfile(InstanceContainer): identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces) for identifier in identifiers: - machine_id = product_id_map.get(identifier.get("product"), None) - if machine_id is None: - # Lets try again with some naive heuristics. - machine_id = identifier.get("product").replace(" ", "").lower() + machine_id_list = product_id_map.get(identifier.get("product"), []) + if not machine_id_list: + machine_id_list.append(identifier.get("product").replace(" ", "").lower()) - definitions = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id) - if not definitions: - Logger.log("w", "No definition found for machine ID %s", machine_id) - continue - - definition = definitions[0] - - machine_manufacturer = identifier.get("manufacturer", definition.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition. - - if machine_compatibility: - new_material_id = self.getId() + "_" + machine_id - - # The child or derived material container may already exist. This can happen when a material in a - # project file and the a material in Cura have the same ID. - # In the case if a derived material already exists, override that material container because if - # the data in the parent material has been changed, the derived ones should be updated too. - if ContainerRegistry.getInstance().isLoaded(new_material_id): - new_material = ContainerRegistry.getInstance().findContainers(id = new_material_id)[0] - is_new_material = False - else: - new_material = XmlMaterialProfile(new_material_id) - is_new_material = True - - new_material.setMetaData(copy.deepcopy(self.getMetaData())) - new_material.getMetaData()["id"] = new_material_id - new_material.getMetaData()["name"] = self.getName() - new_material.setDefinition(machine_id) - # Don't use setMetadata, as that overrides it for all materials with same base file - new_material.getMetaData()["compatible"] = machine_compatibility - new_material.getMetaData()["machine_manufacturer"] = machine_manufacturer - new_material.getMetaData()["definition"] = machine_id - - new_material.setCachedValues(cached_machine_setting_properties) - - new_material._dirty = False - - if is_new_material: - containers_to_add.append(new_material) - - hotends = machine.iterfind("./um:hotend", self.__namespaces) - for hotend in hotends: - hotend_id = hotend.get("id") - if hotend_id is None: + for machine_id in machine_id_list: + definitions = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id) + if not definitions: + Logger.log("w", "No definition found for machine ID %s", machine_id) continue - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id) - if not variant_containers: - # It is not really properly defined what "ID" is so also search for variants by name. - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = definition["id"], name = hotend_id) + definition = definitions[0] - if not variant_containers: - continue + machine_manufacturer = identifier.get("manufacturer", definition.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition. - hotend_compatibility = machine_compatibility - hotend_setting_values = {} - settings = hotend.iterfind("./um:setting", self.__namespaces) - for entry in settings: - key = entry.get("key") - if key in self.__material_settings_setting_map: - hotend_setting_values[self.__material_settings_setting_map[key]] = entry.text - elif key in self.__unmapped_settings: - if key == "hardware compatible": - hotend_compatibility = self._parseCompatibleValue(entry.text) + if machine_compatibility: + new_material_id = self.getId() + "_" + machine_id + + # The child or derived material container may already exist. This can happen when a material in a + # project file and the a material in Cura have the same ID. + # In the case if a derived material already exists, override that material container because if + # the data in the parent material has been changed, the derived ones should be updated too. + if ContainerRegistry.getInstance().isLoaded(new_material_id): + new_material = ContainerRegistry.getInstance().findContainers(id = new_material_id)[0] + is_new_material = False else: - Logger.log("d", "Unsupported material setting %s", key) + new_material = XmlMaterialProfile(new_material_id) + is_new_material = True - new_hotend_id = self.getId() + "_" + machine_id + "_" + hotend_id.replace(" ", "_") + new_material.setMetaData(copy.deepcopy(self.getMetaData())) + new_material.getMetaData()["id"] = new_material_id + new_material.getMetaData()["name"] = self.getName() + new_material.setDefinition(machine_id) + # Don't use setMetadata, as that overrides it for all materials with same base file + new_material.getMetaData()["compatible"] = machine_compatibility + new_material.getMetaData()["machine_manufacturer"] = machine_manufacturer + new_material.getMetaData()["definition"] = machine_id - # Same as machine compatibility, keep the derived material containers consistent with the parent - # material - if ContainerRegistry.getInstance().isLoaded(new_hotend_id): - new_hotend_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_id)[0] - is_new_material = False - else: - new_hotend_material = XmlMaterialProfile(new_hotend_id) - is_new_material = True + new_material.setCachedValues(cached_machine_setting_properties) - new_hotend_material.setMetaData(copy.deepcopy(self.getMetaData())) - new_hotend_material.getMetaData()["id"] = new_hotend_id - new_hotend_material.getMetaData()["name"] = self.getName() - new_hotend_material.getMetaData()["variant"] = variant_containers[0]["id"] - # Don't use setMetadata, as that overrides it for all materials with same base file - new_hotend_material.getMetaData()["compatible"] = hotend_compatibility - new_hotend_material.getMetaData()["machine_manufacturer"] = machine_manufacturer - new_hotend_material.getMetaData()["definition"] = machine_id + new_material._dirty = False - cached_hotend_setting_properties = cached_machine_setting_properties.copy() - cached_hotend_setting_properties.update(hotend_setting_values) + if is_new_material: + containers_to_add.append(new_material) - new_hotend_material.setCachedValues(cached_hotend_setting_properties) + hotends = machine.iterfind("./um:hotend", self.__namespaces) + for hotend in hotends: + hotend_id = hotend.get("id") + if hotend_id is None: + continue - new_hotend_material._dirty = False + variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id) + if not variant_containers: + # It is not really properly defined what "ID" is so also search for variants by name. + variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = definition["id"], name = hotend_id) - if is_new_material: - containers_to_add.append(new_hotend_material) + if not variant_containers: + continue + + hotend_compatibility = machine_compatibility + hotend_setting_values = {} + settings = hotend.iterfind("./um:setting", self.__namespaces) + for entry in settings: + key = entry.get("key") + if key in self.__material_settings_setting_map: + hotend_setting_values[self.__material_settings_setting_map[key]] = entry.text + elif key in self.__unmapped_settings: + if key == "hardware compatible": + hotend_compatibility = self._parseCompatibleValue(entry.text) + else: + Logger.log("d", "Unsupported material setting %s", key) + + new_hotend_id = self.getId() + "_" + machine_id + "_" + hotend_id.replace(" ", "_") + + # Same as machine compatibility, keep the derived material containers consistent with the parent + # material + if ContainerRegistry.getInstance().isLoaded(new_hotend_id): + new_hotend_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_id)[0] + is_new_material = False + else: + new_hotend_material = XmlMaterialProfile(new_hotend_id) + is_new_material = True + + new_hotend_material.setMetaData(copy.deepcopy(self.getMetaData())) + new_hotend_material.getMetaData()["id"] = new_hotend_id + new_hotend_material.getMetaData()["name"] = self.getName() + new_hotend_material.getMetaData()["variant"] = variant_containers[0]["id"] + # Don't use setMetadata, as that overrides it for all materials with same base file + new_hotend_material.getMetaData()["compatible"] = hotend_compatibility + new_hotend_material.getMetaData()["machine_manufacturer"] = machine_manufacturer + new_hotend_material.getMetaData()["definition"] = machine_id + + cached_hotend_setting_properties = cached_machine_setting_properties.copy() + cached_hotend_setting_properties.update(hotend_setting_values) + + new_hotend_material.setCachedValues(cached_hotend_setting_properties) + + new_hotend_material._dirty = False + + if is_new_material: + containers_to_add.append(new_hotend_material) + + # there is only one ID for a machine. Once we have reached here, it means we have already found + # a workable ID for that machine, so there is no need to continue + break for container_to_add in containers_to_add: ContainerRegistry.getInstance().addContainer(container_to_add) @@ -720,79 +725,84 @@ class XmlMaterialProfile(InstanceContainer): machine_compatibility = cls._parseCompatibleValue(entry.text) for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces): - machine_id = product_id_map.get(identifier.get("product"), None) - if machine_id is None: - # Lets try again with some naive heuristics. - machine_id = identifier.get("product").replace(" ", "").lower() - definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id) - if not definition_metadata: - Logger.log("w", "No definition found for machine ID %s", machine_id) - continue - definition_metadata = definition_metadata[0] + machine_id_list = product_id_map.get(identifier.get("product"), []) + if not machine_id_list: + machine_id_list.append(identifier.get("product").replace(" ", "").lower()) - machine_manufacturer = identifier.get("manufacturer", definition_metadata.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition. - - if machine_compatibility: - new_material_id = container_id + "_" + machine_id - - # The child or derived material container may already exist. This can happen when a material in a - # project file and the a material in Cura have the same ID. - # In the case if a derived material already exists, override that material container because if - # the data in the parent material has been changed, the derived ones should be updated too. - found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_material_id) - if found_materials: - new_material_metadata = found_materials[0] - else: - new_material_metadata = {} - - new_material_metadata.update(base_metadata) - new_material_metadata["id"] = new_material_id - new_material_metadata["compatible"] = machine_compatibility - new_material_metadata["machine_manufacturer"] = machine_manufacturer - new_material_metadata["definition"] = machine_id - - if len(found_materials) == 0: #This is a new material. - result_metadata.append(new_material_metadata) - - for hotend in machine.iterfind("./um:hotend", cls.__namespaces): - hotend_id = hotend.get("id") - if hotend_id is None: + for machine_id in machine_id_list: + definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id) + if not definition_metadata: + Logger.log("w", "No definition found for machine ID %s", machine_id) continue + definition_metadata = definition_metadata[0] - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id) - if not variant_containers: - # It is not really properly defined what "ID" is so also search for variants by name. - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id) + machine_manufacturer = identifier.get("manufacturer", definition_metadata.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition. - hotend_compatibility = machine_compatibility - for entry in hotend.iterfind("./um:setting", cls.__namespaces): - key = entry.get("key") - if key == "hardware compatible": - hotend_compatibility = cls._parseCompatibleValue(entry.text) + if machine_compatibility: + new_material_id = container_id + "_" + machine_id - new_hotend_id = container_id + "_" + machine_id + "_" + hotend_id.replace(" ", "_") + # The child or derived material container may already exist. This can happen when a material in a + # project file and the a material in Cura have the same ID. + # In the case if a derived material already exists, override that material container because if + # the data in the parent material has been changed, the derived ones should be updated too. + found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_material_id) + if found_materials: + new_material_metadata = found_materials[0] + else: + new_material_metadata = {} - # Same as machine compatibility, keep the derived material containers consistent with the parent - # material - found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_hotend_id) - if found_materials: - new_hotend_material_metadata = found_materials[0] - else: - new_hotend_material_metadata = {} + new_material_metadata.update(base_metadata) + new_material_metadata["id"] = new_material_id + new_material_metadata["compatible"] = machine_compatibility + new_material_metadata["machine_manufacturer"] = machine_manufacturer + new_material_metadata["definition"] = machine_id - new_hotend_material_metadata.update(base_metadata) - if variant_containers: - new_hotend_material_metadata["variant"] = variant_containers[0]["id"] - else: - new_hotend_material_metadata["variant"] = hotend_id - _with_missing_variants.append(new_hotend_material_metadata) - new_hotend_material_metadata["compatible"] = hotend_compatibility - new_hotend_material_metadata["machine_manufacturer"] = machine_manufacturer - new_hotend_material_metadata["id"] = new_hotend_id - new_hotend_material_metadata["definition"] = machine_id + if len(found_materials) == 0: #This is a new material. + result_metadata.append(new_material_metadata) - if len(found_materials) == 0: - result_metadata.append(new_hotend_material_metadata) + for hotend in machine.iterfind("./um:hotend", cls.__namespaces): + hotend_id = hotend.get("id") + if hotend_id is None: + continue + + variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id) + if not variant_containers: + # It is not really properly defined what "ID" is so also search for variants by name. + variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id) + + hotend_compatibility = machine_compatibility + for entry in hotend.iterfind("./um:setting", cls.__namespaces): + key = entry.get("key") + if key == "hardware compatible": + hotend_compatibility = cls._parseCompatibleValue(entry.text) + + new_hotend_id = container_id + "_" + machine_id + "_" + hotend_id.replace(" ", "_") + + # Same as machine compatibility, keep the derived material containers consistent with the parent + # material + found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_hotend_id) + if found_materials: + new_hotend_material_metadata = found_materials[0] + else: + new_hotend_material_metadata = {} + + new_hotend_material_metadata.update(base_metadata) + if variant_containers: + new_hotend_material_metadata["variant"] = variant_containers[0]["id"] + else: + new_hotend_material_metadata["variant"] = hotend_id + _with_missing_variants.append(new_hotend_material_metadata) + new_hotend_material_metadata["compatible"] = hotend_compatibility + new_hotend_material_metadata["machine_manufacturer"] = machine_manufacturer + new_hotend_material_metadata["id"] = new_hotend_id + new_hotend_material_metadata["definition"] = machine_id + + if len(found_materials) == 0: + result_metadata.append(new_hotend_material_metadata) + + # there is only one ID for a machine. Once we have reached here, it means we have already found + # a workable ID for that machine, so there is no need to continue + break return result_metadata @@ -818,10 +828,32 @@ class XmlMaterialProfile(InstanceContainer): # # This loads the mapping from a file. @classmethod - def getProductIdMap(cls) -> Dict[str, str]: + def getProductIdMap(cls) -> Dict[str, List[str]]: product_to_id_file = os.path.join(os.path.dirname(sys.modules[cls.__module__].__file__), "product_to_id.json") with open(product_to_id_file) as f: - return json.load(f) + product_to_id_map = json.load(f) + + # generate a few more combinations so it can be smart about finding IDs + product_to_id_map = {key: [value] for key, value in product_to_id_map.items()} + for name, id_list in product_to_id_map.items(): + name_parts = name.split(" ") + merged_name_parts = [] + for part in name_parts: + if len(part) == 0: + continue + if len(merged_name_parts) == 0: + merged_name_parts.append(part.lower()) + continue + if part.isdigit(): + # for names with digit(s) such as Ultimaker 3 Extended, we generate an ID like + # "ultimaker3_extended", ignoring the space between "Ultimaker" and "3". + merged_name_parts[-1] = merged_name_parts[-1] + part.lower() + + generated_id = "_".join(merged_name_parts) + if generated_id not in id_list: + id_list.append(generated_id) + + return product_to_id_map ## Parse the value of the "material compatible" property. @classmethod From 7cd344978149997d91d91c1f20788e42fe3de91e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 13 Dec 2017 11:26:16 +0100 Subject: [PATCH 2/5] Fix material loading --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 08530f96e2..4de49817bc 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -632,9 +632,9 @@ class XmlMaterialProfile(InstanceContainer): if is_new_material: containers_to_add.append(new_hotend_material) - # there is only one ID for a machine. Once we have reached here, it means we have already found - # a workable ID for that machine, so there is no need to continue - break + # there is only one ID for a machine. Once we have reached here, it means we have already found + # a workable ID for that machine, so there is no need to continue + break for container_to_add in containers_to_add: ContainerRegistry.getInstance().addContainer(container_to_add) @@ -800,9 +800,9 @@ class XmlMaterialProfile(InstanceContainer): if len(found_materials) == 0: result_metadata.append(new_hotend_material_metadata) - # there is only one ID for a machine. Once we have reached here, it means we have already found - # a workable ID for that machine, so there is no need to continue - break + # there is only one ID for a machine. Once we have reached here, it means we have already found + # a workable ID for that machine, so there is no need to continue + break return result_metadata From 5c5f08e9ca3bdf84f04a7e9c6d31c73c52d3f93b Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Wed, 13 Dec 2017 11:58:59 +0100 Subject: [PATCH 3/5] Do not slice a model if it is only one on a build plane and has setting from non_printing_mesh CURA-4703 --- plugins/CuraEngineBackend/StartSliceJob.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 876b4685cc..7cfccb2b1f 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -131,12 +131,21 @@ class StartSliceJob(Job): Logger.log("w", "No objects suitable for one at a time found, or no correct order found") else: temp_list = [] + is_non_printing_mesh = False for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: - if not getattr(node, "_outside_buildarea", False) or getattr(node, "_non_printing_mesh", False): + _non_printing_mesh = getattr(node, "_non_printing_mesh", False) + if not getattr(node, "_outside_buildarea", False) or _non_printing_mesh: temp_list.append(node) + if _non_printing_mesh: + is_non_printing_mesh = True Job.yieldThread() + #If list has one node and it has non printing settings then remove it from list + # otherwise CuraEngine will crash + if len(temp_list) == 1 and is_non_printing_mesh: + temp_list.clear() + if temp_list: object_groups.append(temp_list) From 6e6dc493f1bdd8f9027341dcc869cab295f7625e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 13 Dec 2017 12:27:15 +0100 Subject: [PATCH 4/5] Fix material loading for unknown names --- cura/Settings/CuraContainerStack.py | 4 +- .../XmlMaterialProfile/XmlMaterialProfile.py | 54 +++++++++++-------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index 9e30e3dd66..61c28df570 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -508,7 +508,7 @@ class CuraContainerStack(ContainerStack): def findDefaultQuality(self) -> Optional[ContainerInterface]: definition = self._getMachineDefinition() registry = ContainerRegistry.getInstance() - material_container = self.material if self.material != self._empty_instance_container else None + material_container = self.material if self.material.getId() not in (self._empty_material.getId(), self._empty_instance_container.getId()) else None search_criteria = {"type": "quality"} @@ -552,7 +552,7 @@ class CuraContainerStack(ContainerStack): material_search_criteria = {"type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"} if definition.getMetaDataEntry("has_machine_quality"): if self.material != self._empty_instance_container: - material_search_criteria["definition"] = material_container.getDefinition().id + material_search_criteria["definition"] = material_container.getMetaDataEntry("definition") if definition.getMetaDataEntry("has_variants"): material_search_criteria["variant"] = material_container.getMetaDataEntry("variant") diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 4de49817bc..e212ab9b7c 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -533,7 +533,7 @@ class XmlMaterialProfile(InstanceContainer): for identifier in identifiers: machine_id_list = product_id_map.get(identifier.get("product"), []) if not machine_id_list: - machine_id_list.append(identifier.get("product").replace(" ", "").lower()) + machine_id_list = self.getPossibleDefinitionIDsFromName(identifier.get("product")) for machine_id in machine_id_list: definitions = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id) @@ -541,6 +541,7 @@ class XmlMaterialProfile(InstanceContainer): Logger.log("w", "No definition found for machine ID %s", machine_id) continue + Logger.log("d", "Found definition for machine ID %s", machine_id) definition = definitions[0] machine_manufacturer = identifier.get("manufacturer", definition.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition. @@ -584,7 +585,7 @@ class XmlMaterialProfile(InstanceContainer): variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id) if not variant_containers: # It is not really properly defined what "ID" is so also search for variants by name. - variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = definition["id"], name = hotend_id) + variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id) if not variant_containers: continue @@ -617,6 +618,7 @@ class XmlMaterialProfile(InstanceContainer): new_hotend_material.getMetaData()["id"] = new_hotend_id new_hotend_material.getMetaData()["name"] = self.getName() new_hotend_material.getMetaData()["variant"] = variant_containers[0]["id"] + new_hotend_material.setDefinition(machine_id) # Don't use setMetadata, as that overrides it for all materials with same base file new_hotend_material.getMetaData()["compatible"] = hotend_compatibility new_hotend_material.getMetaData()["machine_manufacturer"] = machine_manufacturer @@ -727,13 +729,15 @@ class XmlMaterialProfile(InstanceContainer): for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces): machine_id_list = product_id_map.get(identifier.get("product"), []) if not machine_id_list: - machine_id_list.append(identifier.get("product").replace(" ", "").lower()) + machine_id_list = cls.getPossibleDefinitionIDsFromName(identifier.get("product")) for machine_id in machine_id_list: definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id) if not definition_metadata: Logger.log("w", "No definition found for machine ID %s", machine_id) continue + + Logger.log("d", "========= Found def for machine [%s]", machine_id) definition_metadata = definition_metadata[0] machine_manufacturer = identifier.get("manufacturer", definition_metadata.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition. @@ -823,6 +827,30 @@ class XmlMaterialProfile(InstanceContainer): else: return material_name + @classmethod + def getPossibleDefinitionIDsFromName(cls, name): + name_parts = name.lower().split(" ") + merged_name_parts = [] + for part in name_parts: + if len(part) == 0: + continue + if len(merged_name_parts) == 0: + merged_name_parts.append(part) + continue + if part.isdigit(): + # for names with digit(s) such as Ultimaker 3 Extended, we generate an ID like + # "ultimaker3_extended", ignoring the space between "Ultimaker" and "3". + merged_name_parts[-1] = merged_name_parts[-1] + part + else: + merged_name_parts.append(part) + + id_list = [name.lower().replace(" ", ""), # simply removing all spaces + name.lower().replace(" ", "_"), # simply replacing all spaces with underscores + "_".join(merged_name_parts), + ] + + return id_list + ## Gets a mapping from product names in the XML files to their definition # IDs. # @@ -832,27 +860,7 @@ class XmlMaterialProfile(InstanceContainer): product_to_id_file = os.path.join(os.path.dirname(sys.modules[cls.__module__].__file__), "product_to_id.json") with open(product_to_id_file) as f: product_to_id_map = json.load(f) - - # generate a few more combinations so it can be smart about finding IDs product_to_id_map = {key: [value] for key, value in product_to_id_map.items()} - for name, id_list in product_to_id_map.items(): - name_parts = name.split(" ") - merged_name_parts = [] - for part in name_parts: - if len(part) == 0: - continue - if len(merged_name_parts) == 0: - merged_name_parts.append(part.lower()) - continue - if part.isdigit(): - # for names with digit(s) such as Ultimaker 3 Extended, we generate an ID like - # "ultimaker3_extended", ignoring the space between "Ultimaker" and "3". - merged_name_parts[-1] = merged_name_parts[-1] + part.lower() - - generated_id = "_".join(merged_name_parts) - if generated_id not in id_list: - id_list.append(generated_id) - return product_to_id_map ## Parse the value of the "material compatible" property. From 9ea011901132bfa16ab99cb56a39ecb7bd116493 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 13 Dec 2017 12:58:24 +0100 Subject: [PATCH 5/5] Rename 'exception' to 'error' Error is a less technical term, so it's more user friendly. --- cura/CrashHandler.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py index cb0f121d47..81eca67a46 100644 --- a/cura/CrashHandler.py +++ b/cura/CrashHandler.py @@ -59,7 +59,7 @@ class CrashHandler: self.data = dict() self.data["time_stamp"] = time.time() - Logger.log("c", "An uncaught exception has occurred!") + Logger.log("c", "An uncaught error has occurred!") for line in traceback.format_exception(exception_type, value, tb): for part in line.rstrip("\n").split("\n"): Logger.log("c", part) @@ -90,7 +90,7 @@ class CrashHandler: def _messageWidget(self): label = QLabel() - label.setText(catalog.i18nc("@label crash message", """

A fatal exception has occurred. Please send us this Crash Report to fix the problem

+ label.setText(catalog.i18nc("@label crash message", """

A fatal error has occurred. Please send us this Crash Report to fix the problem

Please use the "Send report" button to post a bug report automatically to our servers

""")) @@ -143,7 +143,7 @@ class CrashHandler: def _exceptionInfoWidget(self): group = QGroupBox() - group.setTitle(catalog.i18nc("@title:groupbox", "Exception traceback")) + group.setTitle(catalog.i18nc("@title:groupbox", "Error traceback")) layout = QVBoxLayout() text_area = QTextEdit()