diff --git a/plugins/UFPWriter/UFPWriter.py b/plugins/UFPWriter/UFPWriter.py index ceb9d79087..a85ee489cb 100644 --- a/plugins/UFPWriter/UFPWriter.py +++ b/plugins/UFPWriter/UFPWriter.py @@ -13,6 +13,7 @@ from UM.PluginRegistry import PluginRegistry #To get the g-code writer. from PyQt5.QtCore import QBuffer from cura.Snapshot import Snapshot +from cura.Utils.Threading import call_on_qt_thread from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -29,6 +30,11 @@ class UFPWriter(MeshWriter): Logger.log("d", "Creating thumbnail image...") self._snapshot = Snapshot.snapshot(width = 300, height = 300) + # This needs to be called on the main thread (Qt thread) because the serialization of material containers can + # trigger loading other containers. Because those loaded containers are QtObjects, they must be created on the + # Qt thread. The File read/write operations right now are executed on separated threads because they are scheduled + # by the Job class. + @call_on_qt_thread def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode): archive = VirtualFile() archive.openStream(stream, "application/x-ufp", OpenMode.WriteOnly) @@ -60,5 +66,50 @@ class UFPWriter(MeshWriter): else: Logger.log("d", "Thumbnail not created, cannot save it") + # Store the material. + application = Application.getInstance() + machine_manager = application.getMachineManager() + material_manager = application.getMaterialManager() + global_stack = machine_manager.activeMachine + + material_extension = "xml.fdm_material" + material_mime_type = "application/x-ultimaker-material-profile" + + try: + archive.addContentType(extension = material_extension, mime_type = material_mime_type) + except: + Logger.log("w", "The material extension: %s was already added", material_extension) + + added_materials = [] + for extruder_stack in global_stack.extruders.values(): + material = extruder_stack.material + material_file_name = material.getMetaData()["base_file"] + ".xml.fdm_material" + material_file_name = "/Materials/" + material_file_name + + #Same material cannot be added + if material_file_name in added_materials: + continue + + material_root_id = material.getMetaDataEntry("base_file") + material_group = material_manager.getMaterialGroup(material_root_id) + if material_group is None: + Logger.log("e", "Cannot find material container with root id [%s]", material_root_id) + return False + + material_container = material_group.root_material_node.getContainer() + try: + serialized_material = material_container.serialize() + except NotImplementedError: + Logger.log("e", "Unable serialize material container with root id: %s", material_root_id) + return False + + material_file = archive.getStream(material_file_name) + material_file.write(serialized_material.encode("UTF-8")) + archive.addRelation(virtual_path = material_file_name, + relation_type = "http://schemas.ultimaker.org/package/2018/relationships/material", + origin = "/3D/model.gcode") + + added_materials.append(material_file_name) + archive.close() return True