mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-11 16:57:51 -06:00
Fix merge conflicts with master
This commit is contained in:
commit
4e5d08f320
153 changed files with 5127 additions and 3586 deletions
|
@ -1,3 +1,88 @@
|
|||
[4.0.0]
|
||||
*Updated user interface
|
||||
Ultimaker Cura is a very powerful tool with many features to support users’ needs. In the new UI, we present these features in a better, more intuitive way based on the workflow of our users. The Marketplace and user account control have been integrated into the main interface to easily access material profiles and plugins. Three stages are shown in the header to give a clear guidance of the flow. The stage menu is populated with collapsible panels that allow users to focus on the 3D view when needed, while still showing important information at the same time, such as slicing configuration and settings. Users can now easily go to the preview stage to examine the layer view after slicing the model, which previously was less obvious or hidden. The new UI also creates more distinction between recommended and custom mode. Novice users or users who are not interested in all the settings can easily prepare a file, relying on the strength of expert-configured print profiles. Experienced users who want greater control can configure over 300 settings to their needs.
|
||||
|
||||
*Redesigned "Add Printer" dialog
|
||||
Updated one of the first dialogs a new user is presented with. The layout is loosely modeled on the layout of the Ultimaker 3/Ultimaker S5 "Connect to Network" dialog, and adds some instructions and intention to the dialog. Contributed by fieldOfView.
|
||||
|
||||
*Updated custom mode panel
|
||||
Based on feedback from 4.0 beta, the custom mode panel is now resizable to make more settings visible. The set position will persist between sessions.
|
||||
|
||||
*Monitor tab
|
||||
Updated the monitor tab interface for better alignment with Cura Connect interface.
|
||||
|
||||
*Remote printing
|
||||
Use your Ultimaker S5 printer with an Ultimaker account to send and monitor print jobs from outside your local network. Requires firmware 5.2 (coming soon).
|
||||
|
||||
*User ratings for plugins
|
||||
With an Ultimaker account, users can now give feedback on their experience by rating their favourite plugins.
|
||||
|
||||
*Integrated backups
|
||||
‘Cura backups’ has been integrated into Ultimaker Cura and can be found in the ‘extensions’ menu. With this feature, users can use their Ultimaker account to backup their Ultimaker Cura configurations to the cloud for easy, convenient retrieval.
|
||||
|
||||
*Plugin versioning
|
||||
Newer plug-ins can't load in older versions if they use newer features, while old plug-ins may still load in newer versions.
|
||||
|
||||
*LAN and cloud printer icons
|
||||
Users can now quickly see if their printer is network or cloud enabled with new icons.
|
||||
|
||||
*Improved UI speed
|
||||
This version switches faster between extruders and printers. Your mileage may vary depending on your system specifications.
|
||||
|
||||
*Floats precision
|
||||
No settings in Ultimaker Cura require more than three digits of precision, so floats in setting input fields have been limited to three digits only. Contributed by fieldOfView.
|
||||
|
||||
*Minimum support area
|
||||
This feature allows set minimum area size for support and support interface polygons. Polygons which area are smaller than set value will not be generated. Contributed by vgribinchuk/Desktop Metal.
|
||||
|
||||
*Lazy Tree Support calculation
|
||||
In previous versions, 95% of Tree Support’s computation time was used to calculate the collision volumes to make sure that the branches avoid collisions with the meshes. Now it calculates these volumes only when necessary, reducing the computation time. Contributed by bjude.
|
||||
|
||||
*CPE and CPE+ comb retractions
|
||||
Changed all CPE and CPE+ profiles to travel up to 50 mm without retraction, decreasing blobs caused by combing long distances.
|
||||
|
||||
*Marketplace improvements
|
||||
Added optimizations to show a support site instead of an email address, increased the number of lines that are shown for the description, and show a 'website' link so people can order material directly.
|
||||
|
||||
*Arduino drivers silent install
|
||||
Previous versions stopped silent installation because the Arduino drivers packaged with Cura are not signed. Arduino drivers are now skipped when performing a silent install.
|
||||
|
||||
*New third-party definitions
|
||||
- Wanhao. Updated printer profiles to use new travel_speed macro (Contributed by forkineye).
|
||||
- JGAurora A1, A5 and Z-603S (Contributed by pinchies).
|
||||
- Alfawise U20 (Contributed by pinchies).
|
||||
- Cocoon Create ModelMaker (Contributed by pinchies).
|
||||
- Ender-3. Updates to the printer definition (Contributed by stelgenhof).
|
||||
|
||||
*Bug fixes
|
||||
- Fixed an issue which prevented slicing when per extruder settings were changed with a disabled extruder.
|
||||
- Improved handling of non-Ultimaker network connected printers within Ultimaker Cura. Contributed by fieldOfView
|
||||
- Fixed an issue where printing with the second extruder only would retract material unnecessarily.
|
||||
- Fixed an issue where outdated plugins remained partially activated.
|
||||
- Fixed an issue where combing was not working when tweaking Retraction minimum travel.
|
||||
- Fixed an oversized print head collision zone when using print one-at-a-time mode.
|
||||
- Due to inaccuracy of floats in very large prints, the position is reset again several times using "G92 E0" commands.
|
||||
- Improved update checker text for better readability.
|
||||
- Updated the implementation of 3MF in Ultimaker Cura for better consistency with 3MF consortium specifications.
|
||||
- Removed all final and initial print temperature offsets, and increased first layer print temperature to fix under-extrusion problems.
|
||||
- Holding shift and rotating a model on its axis for fine-grained rotations would sometimes pan the camera. This has now been fixed.
|
||||
- Added file type associations for .gcode and .g extensions.
|
||||
- Marked some more profiles as experimental.
|
||||
- Fixed an issue where duplicated PLA with a different label would replace the original PLA entry.
|
||||
- Updated which profile new materials are based when you create a brand new material. Contributed by fieldOfView.
|
||||
- Fixed adhesion type errors on startup.
|
||||
- Fixed an issue where system tray icons would remain when Ultimaker Cura is closed until mouse-over.
|
||||
- Added extra tooltip to give extra information about start/end g-codes.
|
||||
- Fixed an issue where clicking 'Create Account' would go to login instead of sign-up.
|
||||
- Fixed an issue where the legacy profile importer would generate corrupt profiles.
|
||||
- Fixed an issue where Ultimaker Cura could crash on start-up during the upgrading of your configuration to the newest version for some people.
|
||||
- Fixed an issue where Ultimaker Cura would crash after downloading plugin from Marketplace.
|
||||
- Ignores plugins folder when checking files for version upgrade. Start-up is now much faster if you've installed a lot of plugins or have used many versions of Ultimaker Cura.
|
||||
- Fixed an issue where the firmware checker shows up when there is no internet connection.
|
||||
- Fixed an issue where settings could not be made visible again after hiding all settings.
|
||||
- Fixed false configuration error for CC Red 0.6 core after a version upgrade.
|
||||
- Fixed an issue where a warning is issued when selecting a printer with no material loaded. The extruder will now be disabled instead.
|
||||
|
||||
[3.6.0]
|
||||
*Gyroid infill
|
||||
New infill pattern with enhanced strength properties. Gyroid infill is one of the strongest infill types for a given weight, has isotropic properties, and prints relatively fast with reduced material use and a fully connected part interior. Note: Slicing time can increase up to 40 seconds or more, depending on the model. Contributed by smartavionics.
|
||||
|
|
|
@ -12,9 +12,6 @@ catalog = i18nCatalog("cura")
|
|||
from . import MarlinFlavorParser, RepRapFlavorParser
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Class for loading and parsing G-code files
|
||||
class GCodeReader(MeshReader):
|
||||
_flavor_default = "Marlin"
|
||||
|
|
|
@ -36,7 +36,7 @@ class DisplayFilenameAndLayerOnLCD(Script):
|
|||
name = self.getSettingValueByKey("name")
|
||||
else:
|
||||
name = Application.getInstance().getPrintInformation().jobName
|
||||
lcd_text = "M117 " + name + " layer: "
|
||||
lcd_text = "M117 " + name + " layer "
|
||||
i = 0
|
||||
for layer in data:
|
||||
display_text = lcd_text + str(i)
|
||||
|
|
|
@ -37,13 +37,14 @@ class InsertAtLayerChange(Script):
|
|||
for layer in data:
|
||||
# Check that a layer is being printed
|
||||
lines = layer.split("\n")
|
||||
if ";LAYER:" in lines[0]:
|
||||
index = data.index(layer)
|
||||
if self.getSettingValueByKey("insert_location") == "before":
|
||||
layer = gcode_to_add + layer
|
||||
else:
|
||||
layer = layer + gcode_to_add
|
||||
|
||||
data[index] = layer
|
||||
for line in lines:
|
||||
if ";LAYER:" in line:
|
||||
index = data.index(layer)
|
||||
if self.getSettingValueByKey("insert_location") == "before":
|
||||
layer = gcode_to_add + layer
|
||||
else:
|
||||
layer = layer + gcode_to_add
|
||||
|
||||
data[index] = layer
|
||||
break
|
||||
return data
|
||||
|
|
|
@ -85,10 +85,11 @@ class TimeLapse(Script):
|
|||
for layer in data:
|
||||
# Check that a layer is being printed
|
||||
lines = layer.split("\n")
|
||||
if ";LAYER:" in lines[0]:
|
||||
index = data.index(layer)
|
||||
layer += gcode_to_append
|
||||
|
||||
data[index] = layer
|
||||
for line in lines:
|
||||
if ";LAYER:" in line:
|
||||
index = data.index(layer)
|
||||
layer += gcode_to_append
|
||||
|
||||
data[index] = layer
|
||||
break
|
||||
return data
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# Cura PostProcessingPlugin
|
||||
# Author: Amanda de Castilho
|
||||
# Date: January 5,2019
|
||||
|
||||
# Description: This plugin overrides probing command and inserts code to ensure
|
||||
# previous probe measurements are loaded and bed leveling enabled
|
||||
# (searches for G29 and replaces it with M501 & M420 S1)
|
||||
# *** Assumes G29 is in the start code, will do nothing if it isn't ***
|
||||
|
||||
from ..Script import Script
|
||||
|
||||
class UsePreviousProbeMeasurements(Script):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def getSettingDataString(self):
|
||||
return """{
|
||||
"name": "Use Previous Probe Measurements",
|
||||
"key": "UsePreviousProbeMeasurements",
|
||||
"metadata": {},
|
||||
"version": 2,
|
||||
"settings":
|
||||
{
|
||||
"use_previous_measurements":
|
||||
{
|
||||
"label": "Use last measurement?",
|
||||
"description": "Selecting this will remove the G29 probing command and instead ensure previous measurements are loaded and enabled",
|
||||
"type": "bool",
|
||||
"default_value": false
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
def execute(self, data):
|
||||
text = "M501 ;load bed level data\nM420 S1 ;enable bed leveling"
|
||||
if self.getSettingValueByKey("use_previous_measurements"):
|
||||
for layer in data:
|
||||
layer_index = data.index(layer)
|
||||
lines = layer.split("\n")
|
||||
for line in lines:
|
||||
if line.startswith("G29"):
|
||||
line_index = lines.index(line)
|
||||
lines[line_index] = text
|
||||
final_lines = "\n".join(lines)
|
||||
data[layer_index] = final_lines
|
||||
return data
|
41
plugins/UFPReader/UFPReader.py
Normal file
41
plugins/UFPReader/UFPReader.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import cast
|
||||
|
||||
from Charon.VirtualFile import VirtualFile
|
||||
|
||||
from UM.Mesh.MeshReader import MeshReader
|
||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||
from plugins.GCodeReader.GCodeReader import GCodeReader
|
||||
|
||||
|
||||
class UFPReader(MeshReader):
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
MimeTypeDatabase.addMimeType(
|
||||
MimeType(
|
||||
name = "application/x-ufp",
|
||||
comment = "Ultimaker Format Package",
|
||||
suffixes = ["ufp"]
|
||||
)
|
||||
)
|
||||
self._supported_extensions = [".ufp"]
|
||||
|
||||
def _read(self, file_name: str) -> CuraSceneNode:
|
||||
# Open the file
|
||||
archive = VirtualFile()
|
||||
archive.open(file_name)
|
||||
# Get the gcode data from the file
|
||||
gcode_data = archive.getData("/3D/model.gcode")
|
||||
# Convert the bytes stream to string
|
||||
gcode_stream = gcode_data["/3D/model.gcode"].decode("utf-8")
|
||||
|
||||
# Open the GCodeReader to parse the data
|
||||
gcode_reader = cast(GCodeReader, PluginRegistry.getInstance().getPluginObject("GCodeReader"))
|
||||
gcode_reader.preReadFromStream(gcode_stream)
|
||||
return gcode_reader.readFromStream(gcode_stream)
|
26
plugins/UFPReader/__init__.py
Normal file
26
plugins/UFPReader/__init__.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
#Copyright (c) 2019 Ultimaker B.V.
|
||||
#Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from . import UFPReader
|
||||
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
def getMetaData():
|
||||
return {
|
||||
"mesh_reader": [
|
||||
{
|
||||
"mime_type": "application/x-ufp",
|
||||
"extension": "ufp",
|
||||
"description": i18n_catalog.i18nc("@item:inlistbox", "Ultimaker Format Package")
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def register(app):
|
||||
app.addNonSliceableExtension(".ufp")
|
||||
return {"mesh_reader": UFPReader.UFPReader()}
|
||||
|
8
plugins/UFPReader/plugin.json
Normal file
8
plugins/UFPReader/plugin.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "UFP Reader",
|
||||
"author": "Ultimaker B.V.",
|
||||
"version": "1.0.0",
|
||||
"description": "Provides support for reading Ultimaker Format Packages.",
|
||||
"supported_sdk_versions": ["6.0.0"],
|
||||
"i18n-catalog": "cura"
|
||||
}
|
|
@ -28,7 +28,7 @@ class UFPWriter(MeshWriter):
|
|||
MimeTypeDatabase.addMimeType(
|
||||
MimeType(
|
||||
name = "application/x-ufp",
|
||||
comment = "Cura UFP File",
|
||||
comment = "Ultimaker Format Package",
|
||||
suffixes = ["ufp"]
|
||||
)
|
||||
)
|
||||
|
|
|
@ -210,7 +210,7 @@ Item
|
|||
|
||||
Label
|
||||
{
|
||||
text: "All jobs are printed."
|
||||
text: i18n.i18nc("@info", "All jobs are printed.")
|
||||
color: UM.Theme.getColor("monitor_text_primary")
|
||||
font: UM.Theme.getFont("medium") // 14pt, regular
|
||||
}
|
||||
|
|
|
@ -50,7 +50,17 @@ Component
|
|||
MonitorCarousel
|
||||
{
|
||||
id: carousel
|
||||
printers: OutputDevice.receivedPrintJobs ? OutputDevice.printers : [null]
|
||||
printers:
|
||||
{
|
||||
// When printing over the cloud we don't recieve print jobs until there is one, so
|
||||
// unless there's at least one print job we'll be stuck with skeleton loading
|
||||
// indefinitely.
|
||||
if (Cura.MachineManager.activeMachineIsUsingCloudConnection || OutputDevice.receivedPrintJobs)
|
||||
{
|
||||
return OutputDevice.printers
|
||||
}
|
||||
return [null]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -395,9 +395,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
newly_finished_jobs = [job for job in finished_jobs if job not in self._finished_jobs and job.owner == username]
|
||||
for job in newly_finished_jobs:
|
||||
if job.assignedPrinter:
|
||||
job_completed_text = i18n_catalog.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.".format(printer_name=job.assignedPrinter.name, job_name = job.name))
|
||||
job_completed_text = i18n_catalog.i18nc("@info:status", "Printer '{printer_name}' has finished printing '{job_name}'.").format(printer_name=job.assignedPrinter.name, job_name = job.name)
|
||||
else:
|
||||
job_completed_text = i18n_catalog.i18nc("@info:status", "The print job '{job_name}' was finished.".format(job_name = job.name))
|
||||
job_completed_text = i18n_catalog.i18nc("@info:status", "The print job '{job_name}' was finished.").format(job_name = job.name)
|
||||
job_completed_message = Message(text=job_completed_text, title = i18n_catalog.i18nc("@info:status", "Print finished"))
|
||||
job_completed_message.show()
|
||||
|
||||
|
|
|
@ -494,50 +494,27 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
def _onCloudFlowPossible(self) -> None:
|
||||
# Cloud flow is possible, so show the message
|
||||
if not self._start_cloud_flow_message:
|
||||
self._start_cloud_flow_message = Message(
|
||||
text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."),
|
||||
lifetime = 0,
|
||||
image_source = QUrl.fromLocalFile(os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "svg", "cloud-flow-start.svg"
|
||||
)),
|
||||
image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"),
|
||||
option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."),
|
||||
option_state = False
|
||||
)
|
||||
self._start_cloud_flow_message.addAction("", i18n_catalog.i18nc("@action", "Get started"), "", "")
|
||||
self._start_cloud_flow_message.optionToggled.connect(self._onDontAskMeAgain)
|
||||
self._start_cloud_flow_message.actionTriggered.connect(self._onCloudFlowStarted)
|
||||
self._start_cloud_flow_message.show()
|
||||
return
|
||||
self._createCloudFlowStartMessage()
|
||||
if self._start_cloud_flow_message and not self._start_cloud_flow_message.visible:
|
||||
self._start_cloud_flow_message.show()
|
||||
|
||||
def _onCloudPrintingConfigured(self) -> None:
|
||||
if self._start_cloud_flow_message:
|
||||
# Hide the cloud flow start message if it was hanging around already
|
||||
# For example: if the user already had the browser openen and made the association themselves
|
||||
if self._start_cloud_flow_message and self._start_cloud_flow_message.visible:
|
||||
self._start_cloud_flow_message.hide()
|
||||
self._start_cloud_flow_message = None
|
||||
|
||||
# Show the successful pop-up
|
||||
if not self._start_cloud_flow_message:
|
||||
self._cloud_flow_complete_message = Message(
|
||||
text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."),
|
||||
lifetime = 30,
|
||||
image_source = QUrl.fromLocalFile(os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "svg", "cloud-flow-completed.svg"
|
||||
)),
|
||||
image_caption = i18n_catalog.i18nc("@info:status", "Connected!")
|
||||
)
|
||||
# Don't show the review connection link if we're not on the local network
|
||||
if self._application.getMachineManager().activeMachineHasNetworkConnection:
|
||||
self._cloud_flow_complete_message.addAction("", i18n_catalog.i18nc("@action", "Review your connection"), "", "", 1) # TODO: Icon
|
||||
self._cloud_flow_complete_message.actionTriggered.connect(self._onReviewCloudConnection)
|
||||
# Cloud flow is complete, so show the message
|
||||
if not self._cloud_flow_complete_message:
|
||||
self._createCloudFlowCompleteMessage()
|
||||
if self._cloud_flow_complete_message and not self._cloud_flow_complete_message.visible:
|
||||
self._cloud_flow_complete_message.show()
|
||||
|
||||
# Set the machine's cloud flow as complete so we don't ask the user again and again for cloud connected printers
|
||||
active_machine = self._application.getMachineManager().activeMachine
|
||||
if active_machine:
|
||||
active_machine.setMetaDataEntry("do_not_show_cloud_message", True)
|
||||
return
|
||||
|
||||
# Set the machine's cloud flow as complete so we don't ask the user again and again for cloud connected printers
|
||||
active_machine = self._application.getMachineManager().activeMachine
|
||||
if active_machine:
|
||||
active_machine.setMetaDataEntry("do_not_show_cloud_message", True)
|
||||
return
|
||||
|
||||
def _onDontAskMeAgain(self, checked: bool) -> None:
|
||||
active_machine = self._application.getMachineManager().activeMachine # type: Optional[GlobalStack]
|
||||
|
@ -563,11 +540,40 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
|
|||
return
|
||||
|
||||
def _onMachineSwitched(self) -> None:
|
||||
if self._start_cloud_flow_message is not None:
|
||||
# Hide any left over messages
|
||||
if self._start_cloud_flow_message is not None and self._start_cloud_flow_message.visible:
|
||||
self._start_cloud_flow_message.hide()
|
||||
self._start_cloud_flow_message = None
|
||||
if self._cloud_flow_complete_message is not None:
|
||||
if self._cloud_flow_complete_message is not None and self._cloud_flow_complete_message.visible:
|
||||
self._cloud_flow_complete_message.hide()
|
||||
self._cloud_flow_complete_message = None
|
||||
|
||||
# Check for cloud flow again with newly selected machine
|
||||
self.checkCloudFlowIsPossible()
|
||||
|
||||
def _createCloudFlowStartMessage(self):
|
||||
self._start_cloud_flow_message = Message(
|
||||
text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."),
|
||||
lifetime = 0,
|
||||
image_source = QUrl.fromLocalFile(os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "svg", "cloud-flow-start.svg"
|
||||
)),
|
||||
image_caption = i18n_catalog.i18nc("@info:status Ultimaker Cloud is a brand name and shouldn't be translated.", "Connect to Ultimaker Cloud"),
|
||||
option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."),
|
||||
option_state = False
|
||||
)
|
||||
self._start_cloud_flow_message.addAction("", i18n_catalog.i18nc("@action", "Get started"), "", "")
|
||||
self._start_cloud_flow_message.optionToggled.connect(self._onDontAskMeAgain)
|
||||
self._start_cloud_flow_message.actionTriggered.connect(self._onCloudFlowStarted)
|
||||
|
||||
def _createCloudFlowCompleteMessage(self):
|
||||
self._cloud_flow_complete_message = Message(
|
||||
text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."),
|
||||
lifetime = 30,
|
||||
image_source = QUrl.fromLocalFile(os.path.join(
|
||||
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
|
||||
"resources", "svg", "cloud-flow-completed.svg"
|
||||
)),
|
||||
image_caption = i18n_catalog.i18nc("@info:status", "Connected!")
|
||||
)
|
||||
self._cloud_flow_complete_message.addAction("", i18n_catalog.i18nc("@action", "Review your connection"), "", "", 1) # TODO: Icon
|
||||
self._cloud_flow_complete_message.actionTriggered.connect(self._onReviewCloudConnection)
|
|
@ -1,9 +1,12 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.Mesh.MeshWriter import MeshWriter #To get the g-code output.
|
||||
from UM.PluginRegistry import PluginRegistry #To get the g-code output.
|
||||
from UM.Qt.Duration import DurationFormat
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
@ -15,10 +18,11 @@ from cura.PrinterOutput.GenericOutputController import GenericOutputController
|
|||
from .AutoDetectBaudJob import AutoDetectBaudJob
|
||||
from .AvrFirmwareUpdater import AvrFirmwareUpdater
|
||||
|
||||
from io import StringIO #To write the g-code output.
|
||||
from queue import Queue
|
||||
from serial import Serial, SerialException, SerialTimeoutException
|
||||
from threading import Thread, Event
|
||||
from time import time
|
||||
from queue import Queue
|
||||
from typing import Union, Optional, List, cast
|
||||
|
||||
import re
|
||||
|
@ -114,28 +118,29 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
# \param kwargs Keyword arguments.
|
||||
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
|
||||
if self._is_printing:
|
||||
return # Aleady printing
|
||||
return # Already printing
|
||||
self.writeStarted.emit(self)
|
||||
# cancel any ongoing preheat timer before starting a print
|
||||
self._printers[0].getController().stopPreheatTimers()
|
||||
|
||||
CuraApplication.getInstance().getController().setActiveStage("MonitorStage")
|
||||
|
||||
# find the G-code for the active build plate to print
|
||||
active_build_plate_id = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
|
||||
gcode_dict = getattr(CuraApplication.getInstance().getController().getScene(), "gcode_dict")
|
||||
gcode_list = gcode_dict[active_build_plate_id]
|
||||
#Find the g-code to print.
|
||||
gcode_textio = StringIO()
|
||||
gcode_writer = cast(MeshWriter, PluginRegistry.getInstance().getPluginObject("GCodeWriter"))
|
||||
success = gcode_writer.write(gcode_textio, None)
|
||||
if not success:
|
||||
return
|
||||
|
||||
self._printGCode(gcode_list)
|
||||
self._printGCode(gcode_textio.getvalue())
|
||||
|
||||
## Start a print based on a g-code.
|
||||
# \param gcode_list List with gcode (strings).
|
||||
def _printGCode(self, gcode_list: List[str]):
|
||||
# \param gcode The g-code to print.
|
||||
def _printGCode(self, gcode: str):
|
||||
self._gcode.clear()
|
||||
self._paused = False
|
||||
|
||||
for layer in gcode_list:
|
||||
self._gcode.extend(layer.split("\n"))
|
||||
self._gcode.extend(gcode.split("\n"))
|
||||
|
||||
# Reset line number. If this is not done, first line is sometimes ignored
|
||||
self._gcode.insert(0, "M110")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue