Optimize 3MF writer and XML material serialization

CURA-5049
This commit is contained in:
Lipu Fei 2018-03-06 17:05:21 +01:00
parent 3b0a9bf16c
commit 75d9297c7d
2 changed files with 36 additions and 22 deletions

View file

@ -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. # 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.Application import Application
from UM.Logger import Logger
from UM.Preferences import Preferences from UM.Preferences import Preferences
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from cura.Settings.ExtruderManager import ExtruderManager from UM.Workspace.WorkspaceWriter import WorkspaceWriter
import zipfile
from io import StringIO
import configparser
class ThreeMFWorkspaceWriter(WorkspaceWriter): class ThreeMFWorkspaceWriter(WorkspaceWriter):
@ -16,7 +17,10 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
super().__init__() super().__init__()
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode): 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 if not mesh_writer: # We need to have the 3mf mesh writer, otherwise we can't save the entire workspace
return False return False
@ -29,17 +33,17 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
if archive is None: # This happens if there was no mesh data to write. if archive is None: # This happens if there was no mesh data to write.
archive = zipfile.ZipFile(stream, "w", compression = zipfile.ZIP_DEFLATED) 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. # 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 # 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) self._writeContainerToArchive(container, archive)
# Check if the machine has extruders and save all that data as well. # 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) self._writeContainerToArchive(extruder_stack, archive)
for container in extruder_stack.getContainers(): for container in extruder_stack.getContainers():
self._writeContainerToArchive(container, archive) self._writeContainerToArchive(container, archive)
@ -59,9 +63,9 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
version_file = zipfile.ZipInfo("Cura/version.ini") version_file = zipfile.ZipInfo("Cura/version.ini")
version_config_parser = configparser.ConfigParser(interpolation = None) version_config_parser = configparser.ConfigParser(interpolation = None)
version_config_parser.add_section("versions") version_config_parser.add_section("versions")
version_config_parser.set("versions", "cura_version", Application.getInstance().getVersion()) version_config_parser.set("versions", "cura_version", application.getVersion())
version_config_parser.set("versions", "build_type", Application.getInstance().getBuildType()) version_config_parser.set("versions", "build_type", application.getBuildType())
version_config_parser.set("versions", "is_debug_mode", str(Application.getInstance().getIsDebugMode())) version_config_parser.set("versions", "is_debug_mode", str(application.getIsDebugMode()))
version_file_string = StringIO() version_file_string = StringIO()
version_config_parser.write(version_file_string) 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. # Some containers have a base file, which should then be the file to use.
if "base_file" in container.getMetaData(): if "base_file" in container.getMetaData():
base_file = container.getMetaDataEntry("base_file") 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) file_name = "Cura/%s.%s" % (container.getId(), file_suffix)

View file

@ -200,18 +200,25 @@ class XmlMaterialProfile(InstanceContainer):
## Begin Settings Block ## Begin Settings Block
builder.start("settings") builder.start("settings")
if self.getDefinition().getId() == "fdmprinter": if self.getMetaDataEntry("definition") == "fdmprinter":
for instance in self.findInstances(): for instance in self.findInstances():
self._addSettingElement(builder, instance) self._addSettingElement(builder, instance)
machine_container_map = {} machine_container_map = {}
machine_nozzle_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: for container in all_containers:
definition_id = container.getDefinition().getId() definition_id = container.getMetaDataEntry("definition")
if definition_id == "fdmprinter": if definition_id == "fdmprinter":
continue continue
@ -233,7 +240,8 @@ class XmlMaterialProfile(InstanceContainer):
product_id_map = self.getProductIdMap() product_id_map = self.getProductIdMap()
for definition_id, container in machine_container_map.items(): 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 product = definition_id
for product_name, product_id_list in product_id_map.items(): for product_name, product_id_list in product_id_map.items():
@ -243,13 +251,14 @@ class XmlMaterialProfile(InstanceContainer):
builder.start("machine") builder.start("machine")
builder.start("machine_identifier", { 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 "product": product
}) })
builder.end("machine_identifier") builder.end("machine_identifier")
for instance in container.findInstances(): 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. # If the settings match that of the base profile, just skip since we inherit the base profile.
continue continue