From bcfac3ace6a4bc53c42f507103e43d6bf92ec39d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 25 Jan 2018 17:14:32 +0100 Subject: [PATCH 1/3] Added very rough implementation for UCP files --- plugins/UCPWriter/UCPWriter.py | 68 ++++++++++++++++++++++++++++++++++ plugins/UCPWriter/__init__.py | 25 +++++++++++++ plugins/UCPWriter/plugin.json | 8 ++++ 3 files changed, 101 insertions(+) create mode 100644 plugins/UCPWriter/UCPWriter.py create mode 100644 plugins/UCPWriter/__init__.py create mode 100644 plugins/UCPWriter/plugin.json diff --git a/plugins/UCPWriter/UCPWriter.py b/plugins/UCPWriter/UCPWriter.py new file mode 100644 index 0000000000..cd858b912a --- /dev/null +++ b/plugins/UCPWriter/UCPWriter.py @@ -0,0 +1,68 @@ +import zipfile + +from io import StringIO + +from UM.Resources import Resources +from UM.Mesh.MeshWriter import MeshWriter +from UM.Logger import Logger +from UM.PluginRegistry import PluginRegistry + +MYPY = False +try: + if not MYPY: + import xml.etree.cElementTree as ET +except ImportError: + Logger.log("w", "Unable to load cElementTree, switching to slower version") + import xml.etree.ElementTree as ET + + +class UCPWriter(MeshWriter): + def __init__(self): + super().__init__() + self._namespaces = { + "content-types": "http://schemas.openxmlformats.org/package/2006/content-types", + "relationships": "http://schemas.openxmlformats.org/package/2006/relationships", + } + + def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode): + self._archive = None # Reset archive + archive = zipfile.ZipFile(stream, "w", compression=zipfile.ZIP_DEFLATED) + + gcode_file = zipfile.ZipInfo("3D/model.gcode") + gcode_file.compress_type = zipfile.ZIP_DEFLATED + + # Create content types file + content_types_file = zipfile.ZipInfo("[Content_Types].xml") + content_types_file.compress_type = zipfile.ZIP_DEFLATED + content_types = ET.Element("Types", xmlns=self._namespaces["content-types"]) + + rels_type = ET.SubElement(content_types, "Default", Extension="rels", + ContentType="application/vnd.openxmlformats-package.relationships+xml") + gcode_type = ET.SubElement(content_types, "Default", Extension="gcode", + ContentType="text/x-gcode") + image_type = ET.SubElement(content_types, "Default", Extension="png", + ContentType="image/png") + + # Create _rels/.rels file + relations_file = zipfile.ZipInfo("_rels/.rels") + relations_file.compress_type = zipfile.ZIP_DEFLATED + relations_element = ET.Element("Relationships", xmlns=self._namespaces["relationships"]) + + thumbnail_relation_element = ET.SubElement(relations_element, "Relationship", Target="/Metadata/thumbnail.png", Id="rel0", + Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail") + + model_relation_element = ET.SubElement(relations_element, "Relationship", Target="/3D/model.gcode", + Id="rel1", + Type="http://schemas.ultimaker.org/package/2018/relationships/gcode") + + gcode_string = StringIO() + + PluginRegistry.getInstance().getPluginObject("GCodeWriter").write(gcode_string, None) + + archive.write(Resources.getPath(Resources.Images, "cura-icon.png"), "Metadata/thumbnail.png") + + archive.writestr(gcode_file, gcode_string.getvalue()) + archive.writestr(content_types_file, b' \n' + ET.tostring(content_types)) + archive.writestr(relations_file, b' \n' + ET.tostring(relations_element)) + + archive.close() diff --git a/plugins/UCPWriter/__init__.py b/plugins/UCPWriter/__init__.py new file mode 100644 index 0000000000..24a4856c34 --- /dev/null +++ b/plugins/UCPWriter/__init__.py @@ -0,0 +1,25 @@ +# Copyright (c) 2017 Ultimaker B.V. +# Uranium is released under the terms of the LGPLv3 or higher. + +from . import UCPWriter + +from UM.i18n import i18nCatalog + +i18n_catalog = i18nCatalog("cura") + +def getMetaData(): + return { + "mesh_writer": { + "output": [ + { + "mime_type": "application/x-ucp", + "mode": UCPWriter.UCPWriter.OutputMode.BinaryMode, + "extension": "UCP", + "description": i18n_catalog.i18nc("@item:inlistbox", "UCP File (WIP)") + } + ] + } + } + +def register(app): + return { "mesh_writer": UCPWriter.UCPWriter() } diff --git a/plugins/UCPWriter/plugin.json b/plugins/UCPWriter/plugin.json new file mode 100644 index 0000000000..d1e3ce3d1c --- /dev/null +++ b/plugins/UCPWriter/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "UCP Writer", + "author": "Ultimaker B.V.", + "version": "1.0.0", + "description": "Provides support for writing UCP files.", + "api": 4, + "i18n-catalog": "cura" +} From 8c7f8fa1fa8910d633a2b80508714e4da9cbf8d5 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 25 Jan 2018 22:34:28 +0100 Subject: [PATCH 2/3] Fix typo in USBOutputController --- plugins/USBPrinting/USBPrinterOutputController.py | 2 +- plugins/USBPrinting/USBPrinterOutputDevice.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/USBPrinting/USBPrinterOutputController.py b/plugins/USBPrinting/USBPrinterOutputController.py index ba45e7b0ca..f189ed5876 100644 --- a/plugins/USBPrinting/USBPrinterOutputController.py +++ b/plugins/USBPrinting/USBPrinterOutputController.py @@ -10,7 +10,7 @@ if MYPY: from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel -class USBPrinterOuptutController(PrinterOutputController): +class USBPrinterOutputController(PrinterOutputController): def __init__(self, output_device): super().__init__(output_device) diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index d372b54c38..241c026779 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -12,7 +12,7 @@ from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel from .AutoDetectBaudJob import AutoDetectBaudJob -from .USBPrinterOutputController import USBPrinterOuptutController +from .USBPrinterOutputController import USBPrinterOutputController from .avr_isp import stk500v2, intelHex from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty From 6cd64e1ce8d16ce5b3f673a2d6b17d7b39c9519d Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 25 Jan 2018 22:47:48 +0100 Subject: [PATCH 3/3] Two more fixes for typo in USBPrinterOutputController --- plugins/USBPrinting/USBPrinterOutputDevice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 241c026779..b53f502d81 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -237,7 +237,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): container_stack = Application.getInstance().getGlobalContainerStack() num_extruders = container_stack.getProperty("machine_extruder_count", "value") # Ensure that a printer is created. - self._printers = [PrinterOutputModel(output_controller=USBPrinterOuptutController(self), number_of_extruders=num_extruders)] + self._printers = [PrinterOutputModel(output_controller=USBPrinterOutputController(self), number_of_extruders=num_extruders)] self._printers[0].updateName(container_stack.getName()) self.setConnectionState(ConnectionState.connected) self._update_thread.start() @@ -364,7 +364,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice): elapsed_time = int(time() - self._print_start_time) print_job = self._printers[0].activePrintJob if print_job is None: - print_job = PrintJobOutputModel(output_controller = USBPrinterOuptutController(self), name= Application.getInstance().getPrintInformation().jobName) + print_job = PrintJobOutputModel(output_controller = USBPrinterOutputController(self), name= Application.getInstance().getPrintInformation().jobName) print_job.updateState("printing") self._printers[0].updateActivePrintJob(print_job)