mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
Allow for saving multiple scene nodes at the same time
The selection saving saves the entire current selection and their child nodes. Contributes to issue CURA-2617.
This commit is contained in:
parent
b3e3053323
commit
96e516c676
4 changed files with 44 additions and 14 deletions
|
@ -49,7 +49,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
|
||||||
self._printer_state = ""
|
self._printer_state = ""
|
||||||
self._printer_type = "unknown"
|
self._printer_type = "unknown"
|
||||||
|
|
||||||
def requestWrite(self, node, file_name = None, filter_by_machine = False):
|
def requestWrite(self, nodes, file_name = None, filter_by_machine = False):
|
||||||
raise NotImplementedError("requestWrite needs to be implemented")
|
raise NotImplementedError("requestWrite needs to be implemented")
|
||||||
|
|
||||||
## Signals
|
## Signals
|
||||||
|
|
|
@ -46,7 +46,17 @@ class GCodeWriter(MeshWriter):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def write(self, stream, node, mode = MeshWriter.OutputMode.TextMode):
|
## Writes the g-code for the entire scene to a stream.
|
||||||
|
#
|
||||||
|
# Note that even though the function accepts a collection of nodes, the
|
||||||
|
# entire scene is always written to the file since it is not possible to
|
||||||
|
# separate the g-code for just specific nodes.
|
||||||
|
#
|
||||||
|
# \param stream The stream to write the g-code to.
|
||||||
|
# \param nodes This is ignored.
|
||||||
|
# \param mode Additional information on how to format the g-code in the
|
||||||
|
# file. This must always be text mode.
|
||||||
|
def write(self, stream, nodes, mode = MeshWriter.OutputMode.TextMode):
|
||||||
if mode != MeshWriter.OutputMode.TextMode:
|
if mode != MeshWriter.OutputMode.TextMode:
|
||||||
Logger.log("e", "GCode Writer does not support non-text mode.")
|
Logger.log("e", "GCode Writer does not support non-text mode.")
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# Copyright (c) 2016 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
@ -25,7 +28,16 @@ class RemovableDriveOutputDevice(OutputDevice):
|
||||||
self._writing = False
|
self._writing = False
|
||||||
self._stream = None
|
self._stream = None
|
||||||
|
|
||||||
def requestWrite(self, node, file_name = None, filter_by_machine = False):
|
## Request the specified nodes to be written to the removable drive.
|
||||||
|
#
|
||||||
|
# \param nodes A collection of scene nodes that should be written to the
|
||||||
|
# removable drive.
|
||||||
|
# \param file_name \type{string} A suggestion for the file name to write
|
||||||
|
# to. If none is provided, a file name will be made from the names of the
|
||||||
|
# meshes.
|
||||||
|
# \param limit_mimetypes Should we limit the available MIME types to the
|
||||||
|
# MIME types available to the currently active machine?
|
||||||
|
def requestWrite(self, nodes, file_name = None, filter_by_machine = False):
|
||||||
filter_by_machine = True # This plugin is indended to be used by machine (regardless of what it was told to do)
|
filter_by_machine = True # This plugin is indended to be used by machine (regardless of what it was told to do)
|
||||||
if self._writing:
|
if self._writing:
|
||||||
raise OutputDeviceError.DeviceBusyError()
|
raise OutputDeviceError.DeviceBusyError()
|
||||||
|
@ -50,7 +62,7 @@ class RemovableDriveOutputDevice(OutputDevice):
|
||||||
extension = file_formats[0]["extension"]
|
extension = file_formats[0]["extension"]
|
||||||
|
|
||||||
if file_name is None:
|
if file_name is None:
|
||||||
file_name = self._automaticFileName(node)
|
file_name = self._automaticFileName(nodes)
|
||||||
|
|
||||||
if extension: # Not empty string.
|
if extension: # Not empty string.
|
||||||
extension = "." + extension
|
extension = "." + extension
|
||||||
|
@ -60,7 +72,7 @@ class RemovableDriveOutputDevice(OutputDevice):
|
||||||
Logger.log("d", "Writing to %s", file_name)
|
Logger.log("d", "Writing to %s", file_name)
|
||||||
# Using buffering greatly reduces the write time for many lines of gcode
|
# Using buffering greatly reduces the write time for many lines of gcode
|
||||||
self._stream = open(file_name, "wt", buffering = 1)
|
self._stream = open(file_name, "wt", buffering = 1)
|
||||||
job = WriteMeshJob(writer, self._stream, node, MeshWriter.OutputMode.TextMode)
|
job = WriteMeshJob(writer, self._stream, nodes, MeshWriter.OutputMode.TextMode)
|
||||||
job.setFileName(file_name)
|
job.setFileName(file_name)
|
||||||
job.progress.connect(self._onProgress)
|
job.progress.connect(self._onProgress)
|
||||||
job.finished.connect(self._onFinished)
|
job.finished.connect(self._onFinished)
|
||||||
|
@ -86,13 +98,14 @@ class RemovableDriveOutputDevice(OutputDevice):
|
||||||
# The name generated will be the name of one of the nodes. Which node that
|
# The name generated will be the name of one of the nodes. Which node that
|
||||||
# is can not be guaranteed.
|
# is can not be guaranteed.
|
||||||
#
|
#
|
||||||
# \param root A node for which to generate a file name.
|
# \param nodes A collection of nodes for which to generate a file name.
|
||||||
def _automaticFileName(self, root):
|
def _automaticFileName(self, nodes):
|
||||||
for child in BreadthFirstIterator(root):
|
for root in nodes:
|
||||||
if child.getMeshData():
|
for child in BreadthFirstIterator(root):
|
||||||
name = child.getName()
|
if child.getMeshData():
|
||||||
if name:
|
name = child.getName()
|
||||||
return name
|
if name:
|
||||||
|
return name
|
||||||
raise OutputDeviceError.WriteRequestFailedError("Could not find a file name when trying to write to {device}.".format(device = self.getName()))
|
raise OutputDeviceError.WriteRequestFailedError("Could not find a file name when trying to write to {device}.".format(device = self.getName()))
|
||||||
|
|
||||||
def _onProgress(self, job, progress):
|
def _onProgress(self, job, progress):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2016 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from .avr_isp import stk500v2, ispBase, intelHex
|
from .avr_isp import stk500v2, ispBase, intelHex
|
||||||
|
@ -426,7 +426,14 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
||||||
self._error_state = error
|
self._error_state = error
|
||||||
self.onError.emit()
|
self.onError.emit()
|
||||||
|
|
||||||
def requestWrite(self, node, file_name = None, filter_by_machine = False):
|
## Request the current scene to be sent to a USB-connected printer.
|
||||||
|
#
|
||||||
|
# \param nodes A collection of scene nodes to send. This is ignored.
|
||||||
|
# \param file_name \type{string} A suggestion for a file name to write.
|
||||||
|
# This is ignored.
|
||||||
|
# \param filter_by_machine Whether to filter MIME types by machine. This
|
||||||
|
# is ignored.
|
||||||
|
def requestWrite(self, nodes, file_name = None, filter_by_machine = False):
|
||||||
Application.getInstance().showPrintMonitor.emit(True)
|
Application.getInstance().showPrintMonitor.emit(True)
|
||||||
self.startPrint()
|
self.startPrint()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue