From 75d9297c7d664347fb579ae0d01f44bcbaf04832 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 6 Mar 2018 17:05:21 +0100 Subject: [PATCH] Optimize 3MF writer and XML material serialization CURA-5049 --- plugins/3MFWriter/ThreeMFWorkspaceWriter.py | 35 +++++++++++-------- .../XmlMaterialProfile/XmlMaterialProfile.py | 23 ++++++++---- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/plugins/3MFWriter/ThreeMFWorkspaceWriter.py b/plugins/3MFWriter/ThreeMFWorkspaceWriter.py index 507274d355..3f5e69317e 100644 --- a/plugins/3MFWriter/ThreeMFWorkspaceWriter.py +++ b/plugins/3MFWriter/ThreeMFWorkspaceWriter.py @@ -1,14 +1,15 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from UM.Workspace.WorkspaceWriter import WorkspaceWriter +import configparser +from io import StringIO +import zipfile + from UM.Application import Application +from UM.Logger import Logger from UM.Preferences import Preferences from UM.Settings.ContainerRegistry import ContainerRegistry -from cura.Settings.ExtruderManager import ExtruderManager -import zipfile -from io import StringIO -import configparser +from UM.Workspace.WorkspaceWriter import WorkspaceWriter class ThreeMFWorkspaceWriter(WorkspaceWriter): @@ -16,7 +17,10 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter): super().__init__() def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode): - mesh_writer = Application.getInstance().getMeshFileHandler().getWriter("3MFWriter") + application = Application.getInstance() + machine_manager = application.getMachineManager() + + mesh_writer = application.getMeshFileHandler().getWriter("3MFWriter") if not mesh_writer: # We need to have the 3mf mesh writer, otherwise we can't save the entire workspace return False @@ -29,17 +33,17 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter): if archive is None: # This happens if there was no mesh data to write. archive = zipfile.ZipFile(stream, "w", compression = zipfile.ZIP_DEFLATED) - global_container_stack = Application.getInstance().getGlobalContainerStack() + global_stack = machine_manager.activeMachine # Add global container stack data to the archive. - self._writeContainerToArchive(global_container_stack, archive) + self._writeContainerToArchive(global_stack, archive) # Also write all containers in the stack to the file - for container in global_container_stack.getContainers(): + for container in global_stack.getContainers(): self._writeContainerToArchive(container, archive) # Check if the machine has extruders and save all that data as well. - for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()): + for extruder_stack in global_stack.extruders.values(): self._writeContainerToArchive(extruder_stack, archive) for container in extruder_stack.getContainers(): self._writeContainerToArchive(container, archive) @@ -59,9 +63,9 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter): version_file = zipfile.ZipInfo("Cura/version.ini") version_config_parser = configparser.ConfigParser(interpolation = None) version_config_parser.add_section("versions") - version_config_parser.set("versions", "cura_version", Application.getInstance().getVersion()) - version_config_parser.set("versions", "build_type", Application.getInstance().getBuildType()) - version_config_parser.set("versions", "is_debug_mode", str(Application.getInstance().getIsDebugMode())) + version_config_parser.set("versions", "cura_version", application.getVersion()) + version_config_parser.set("versions", "build_type", application.getBuildType()) + version_config_parser.set("versions", "is_debug_mode", str(application.getIsDebugMode())) version_file_string = StringIO() version_config_parser.write(version_file_string) @@ -85,7 +89,8 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter): # Some containers have a base file, which should then be the file to use. if "base_file" in container.getMetaData(): base_file = container.getMetaDataEntry("base_file") - container = ContainerRegistry.getInstance().findContainers(id = base_file)[0] + if base_file != container.getId(): + container = ContainerRegistry.getInstance().findContainers(id = base_file)[0] file_name = "Cura/%s.%s" % (container.getId(), file_suffix) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index edc782cc9e..a7ba423153 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -200,18 +200,25 @@ class XmlMaterialProfile(InstanceContainer): ## Begin Settings Block builder.start("settings") - if self.getDefinition().getId() == "fdmprinter": + if self.getMetaDataEntry("definition") == "fdmprinter": for instance in self.findInstances(): self._addSettingElement(builder, instance) machine_container_map = {} machine_nozzle_map = {} - variant_manager = CuraApplication.getInstance()._variant_manager + variant_manager = CuraApplication.getInstance().getVariantManager() + material_manager = CuraApplication.getInstance().getMaterialManager() + + root_material_id = self.getMetaDataEntry("base_file") # if basefile is self.getId, this is a basefile. + material_group = material_manager.getMaterialGroup(root_material_id) + + all_containers = [] + for node in [material_group.root_material_node] + material_group.derived_material_node_list: + all_containers.append(node.getContainer()) - all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"), base_file = self.getId()) for container in all_containers: - definition_id = container.getDefinition().getId() + definition_id = container.getMetaDataEntry("definition") if definition_id == "fdmprinter": continue @@ -233,7 +240,8 @@ class XmlMaterialProfile(InstanceContainer): product_id_map = self.getProductIdMap() for definition_id, container in machine_container_map.items(): - definition = container.getDefinition() + definition_id = container.getMetaDataEntry("definition") + definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = definition_id)[0] product = definition_id for product_name, product_id_list in product_id_map.items(): @@ -243,13 +251,14 @@ class XmlMaterialProfile(InstanceContainer): builder.start("machine") builder.start("machine_identifier", { - "manufacturer": container.getMetaDataEntry("machine_manufacturer", definition.getMetaDataEntry("manufacturer", "Unknown")), + "manufacturer": container.getMetaDataEntry("machine_manufacturer", + definition_metadata.get("manufacturer", "Unknown")), "product": product }) builder.end("machine_identifier") for instance in container.findInstances(): - if self.getDefinition().getId() == "fdmprinter" and self.getInstance(instance.definition.key) and self.getProperty(instance.definition.key, "value") == instance.value: + if self.getMetaDataEntry("definition") == "fdmprinter" and self.getInstance(instance.definition.key) and self.getProperty(instance.definition.key, "value") == instance.value: # If the settings match that of the base profile, just skip since we inherit the base profile. continue