From e0c7ed85617ba54759ae2c65179ccdedbeb40236 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 May 2016 02:19:39 +0200 Subject: [PATCH] Add a plugin that loads XML materials and an example material --- .../XmlMaterialProfile/XmlMaterialProfile.py | 84 +++++++++++++++++++ plugins/XmlMaterialProfile/__init__.py | 32 +++++++ .../materials/generic_pla.xml.fdm_material | 48 +++++++++++ 3 files changed, 164 insertions(+) create mode 100644 plugins/XmlMaterialProfile/XmlMaterialProfile.py create mode 100644 plugins/XmlMaterialProfile/__init__.py create mode 100644 resources/materials/generic_pla.xml.fdm_material diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py new file mode 100644 index 0000000000..5566301a09 --- /dev/null +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -0,0 +1,84 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +import math +import xml.etree.ElementTree as ET + +import UM.Settings + +def _tag_without_namespace(element): + return element.tag[element.tag.rfind("}") + 1:] + +class XmlMaterialProfile(UM.Settings.InstanceContainer): + def __init__(self, container_id, *args, **kwargs): + super().__init__(container_id, *args, **kwargs) + + def serialize(self): + raise NotImplementedError("Writing material profiles has not yet been implemented") + + def deserialize(self, serialized): + print("deserialize material profile") + data = ET.fromstring(serialized) + + self.addMetaDataEntry("type", "material") + + # TODO: Add material verfication + self.addMetaDataEntry("status", "Unknown") + + metadata = data.iterfind("./um:metadata/*", self.__namespaces) + for entry in metadata: + # The namespace is prepended to the tag name but between {}. + # We are only interested in the actual tag name. + tag_name = entry.tag[entry.tag.rfind("}") + 1:] + + if tag_name == "name": + brand = entry.find("./um:brand", self.__namespaces) + material = entry.find("./um:material", self.__namespaces) + color = entry.find("./um:color", self.__namespaces) + + self.setName("{0} {1} ({2})".format(brand.text, material.text, color.text)) + + self.addMetaDataEntry("brand", brand.text) + self.addMetaDataEntry("material", material.text) + self.addMetaDataEntry("color_name", color.text) + + self.addMetaDataEntry(tag_name, entry.text) + + property_values = {} + properties = data.iterfind("./um:properties/*", self.__namespaces) + for entry in properties: + tag_name = entry.tag[entry.tag.rfind("}") + 1:] + property_values[tag_name] = entry.text + + diameter = float(property_values.get("diameter", 2.85)) # In mm + density = float(property_values.get("density", 1.3)) # In g/cm3 + + weight_per_cm = (math.pi * (diameter / 20) ** 2 * 0.1) * density + + spool_weight = property_values.get("spool_weight") + spool_length = property_values.get("spool_length") + if spool_weight: + length = float(spool_weight) / weight_per_cm + property_values["spool_length"] = str(length / 100) + elif spool_length: + weight = (float(spool_length) * 100) * weight_per_cm + property_values["spool_weight"] = str(weight) + + self.addMetaDataEntry("properties", property_values) + + settings = data.iterfind("./um:settings/um:setting", self.__namespaces) + for entry in settings: + tag_name = _tag_without_namespace(entry) + + if tag_name in self.__material_property_setting_map: + self.setProperty(self.__material_property_setting_map[tag_name], "value", entry.text) + + __material_property_setting_map = { + "print temperature": "material_print_temperature", + "heated bed temperature": "material_bed_temperature", + "standby temperature": "material_standby_temperature", + } + + __namespaces = { + "um": "http://www.ultimaker.com/material" + } diff --git a/plugins/XmlMaterialProfile/__init__.py b/plugins/XmlMaterialProfile/__init__.py new file mode 100644 index 0000000000..041a3f6346 --- /dev/null +++ b/plugins/XmlMaterialProfile/__init__.py @@ -0,0 +1,32 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + +from . import XmlMaterialProfile + +from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase +from UM.i18n import i18nCatalog +catalog = i18nCatalog("cura") + +def getMetaData(): + return { + "plugin": { + "name": catalog.i18nc("@label", "Material Profiles"), + "author": "Ultimaker", + "version": "1.0", + "description": catalog.i18nc("@info:whatsthis", "Provides capabilities to read and write XML-based material profiles."), + "api": 3 + }, + "settings_container": { + "mimetype": "application/x-ultimaker-material-profile" + } + } + +def register(app): + mime_type = MimeType( + name = "application/x-ultimaker-material-profile", + comment = "Ultimaker Material Profile", + suffixes = [ "xml.fdm_material" ] + ) + MimeTypeDatabase.addMimeType(mime_type) + return { "settings_container": XmlMaterialProfile.XmlMaterialProfile("default_xml_material_profile") } + diff --git a/resources/materials/generic_pla.xml.fdm_material b/resources/materials/generic_pla.xml.fdm_material new file mode 100644 index 0000000000..b64ecdc61b --- /dev/null +++ b/resources/materials/generic_pla.xml.fdm_material @@ -0,0 +1,48 @@ + + + + + + Generic + PLA + Generic + + 506c9f0d-e3aa-4bd4-b2d2-23e2425b1aa9 + 0 + #FFFFFF + + + 1.3 + 2.85 + 750 + + + 210 + 60 + 175 + + + + + + 150 + + + + + + + + + 150 + + 80 + + + 100 + + + +