Merge branch 'master' of github.com:ultimaker/Cura into feature_material_editing

* 'master' of github.com:ultimaker/Cura: (38 commits)
  Fixed profile file case-sensitivity.
  Fix UMO Checkup button size
  Remove debug statement and commented-out code CURA-1385
  Show "ready" state when a printer is connected but jobstate is not yet set
  Added deepcopy function
  Made exception handling of slice info plugin way more robust
  Restart timer after slicing is performed when not enabled.
  Update GUID for PLA to match the GUID in the official repository
  Set default extruder index to -1 (so global is default)
  Ensure that the display matches with the backend active extruder data
  Update UM2 Extended build volume height to value published in marketing materials
  Fixed firmware upgrade for um2+
  Capitalise setting label
  CHeckup action now correctly resets every time you start it
  Remove unused name/id when importing a profile from a gcode file
  Just a little typo
  BQ Hephestos2: Heat up nozzle while leveling
  Saving g-code no longer crashes
  Removed update firmware from extensions; This is now handled by machine actions
  Changing active extruder no longer trigger re-slice
  ...
This commit is contained in:
Arjen Hiemstra 2016-07-07 11:29:18 +02:00
commit d8555fe57d
25 changed files with 311 additions and 175 deletions

View file

@ -6,3 +6,6 @@ class MultiMaterialDecorator(SceneNodeDecorator):
def isMultiMaterial(self):
return True
def __deepcopy__(self, memo):
return MultiMaterialDecorator()

View file

@ -44,7 +44,7 @@ class PrintInformation(QObject):
self._current_print_time = Duration(None, self)
self._material_amount = -1
self._material_amounts = []
self._backend = Application.getInstance().getBackend()
if self._backend:
@ -62,21 +62,22 @@ class PrintInformation(QObject):
def currentPrintTime(self):
return self._current_print_time
materialAmountChanged = pyqtSignal()
materialAmountsChanged = pyqtSignal()
@pyqtProperty(float, notify = materialAmountChanged)
def materialAmount(self):
return self._material_amount
@pyqtProperty("QVariantList", notify = materialAmountsChanged)
def materialAmounts(self):
return self._material_amounts
def _onPrintDurationMessage(self, time, amount):
#if self._slice_pass == self.SlicePass.CurrentSettings:
self._current_print_time.setDuration(time)
def _onPrintDurationMessage(self, total_time, material_amounts):
self._current_print_time.setDuration(total_time)
self.currentPrintTimeChanged.emit()
# Material amount is sent as an amount of mm^3, so calculate length from that
r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2
self._material_amount = round((amount / (math.pi * r ** 2)) / 1000, 2)
self.materialAmountChanged.emit()
self._material_amounts = []
for amount in material_amounts:
self._material_amounts.append(round((amount / (math.pi * r ** 2)) / 1000, 2))
self.materialAmountsChanged.emit()
@pyqtSlot(str)
def setJobName(self, name):

View file

@ -24,6 +24,8 @@ class PrinterOutputDevice(QObject, OutputDevice):
self._num_extruders = 1
self._hotend_temperatures = [0] * self._num_extruders
self._target_hotend_temperatures = [0] * self._num_extruders
self._material_ids = [""] * self._num_extruders
self._hotend_ids = [""] * self._num_extruders
self._progress = 0
self._head_x = 0
self._head_y = 0
@ -57,6 +59,12 @@ class PrinterOutputDevice(QObject, OutputDevice):
# Signal to be emitted when head position is changed (x,y,z)
headPositionChanged = pyqtSignal()
# Signal to be emitted when either of the material ids is changed
materialIdChanged = pyqtSignal(int, str, arguments = ["index", "id"])
# Signal to be emitted when either of the hotend ids is changed
hotendIdChanged = pyqtSignal(int, str, arguments = ["index", "id"])
# Signal that is emitted every time connection state is changed.
# it also sends it's own device_id (for convenience sake)
connectionStateChanged = pyqtSignal(str)
@ -212,6 +220,34 @@ class PrinterOutputDevice(QObject, OutputDevice):
self._hotend_temperatures[index] = temperature
self.hotendTemperaturesChanged.emit()
@pyqtProperty("QVariantList", notify = materialIdChanged)
def materialIds(self):
return self._material_ids
## Protected setter for the current material id.
# /param index Index of the extruder
# /param material_id id of the material
def _setMaterialId(self, index, material_id):
if material_id and material_id != "" and material_id != self._material_ids[index]:
Logger.log("d", "Setting material id of hotend %d to %s" % (index, material_id))
self._material_ids[index] = material_id
self.materialIdChanged.emit(index, material_id)
@pyqtProperty("QVariantList", notify = hotendIdChanged)
def hotendIds(self):
return self._hotend_ids
## Protected setter for the current hotend id.
# /param index Index of the extruder
# /param hotend_id id of the hotend
def _setHotendId(self, index, hotend_id):
if hotend_id and hotend_id != "" and hotend_id != self._hotend_ids[index]:
Logger.log("d", "Setting hotend id of hotend %d to %s" % (index, hotend_id))
self._hotend_ids[index] = hotend_id
self.hotendIdChanged.emit(index, hotend_id)
## Attempt to establish connection
def connect(self):
raise NotImplementedError("connect needs to be implemented")

View file

@ -53,7 +53,7 @@ class CuraContainerRegistry(ContainerRegistry):
def _containerExists(self, container_type, container_name):
container_class = ContainerStack if container_type == "machine" else InstanceContainer
return self.findContainers(container_class, id = container_name, type = container_type) or \
return self.findContainers(container_class, id = container_name, type = container_type, ignore_case = True) or \
self.findContainers(container_class, name = container_name, type = container_type)
## Exports an profile to a file

View file

@ -22,7 +22,7 @@ class ExtruderManager(QObject):
def __init__(self, parent = None):
super().__init__(parent)
self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs.
self._active_extruder_index = 0
self._active_extruder_index = -1
UM.Application.getInstance().globalContainerStackChanged.connect(self._addCurrentMachineExtruders)
## Gets the unique identifier of the currently active extruder stack.
@ -66,6 +66,10 @@ class ExtruderManager(QObject):
self._active_extruder_index = index
self.activeExtruderChanged.emit()
@pyqtProperty(int, notify = activeExtruderChanged)
def activeExtruderIndex(self):
return self._active_extruder_index
def getActiveExtruderStack(self):
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
if global_container_stack:

View file

@ -5,6 +5,7 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal
from UM.Application import Application
from UM.Preferences import Preferences
from UM.Logger import Logger
import UM.Settings
@ -50,6 +51,7 @@ class MachineManager(QObject):
active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
self._printer_output_devices = []
Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
if active_machine_id != "":
@ -71,8 +73,52 @@ class MachineManager(QObject):
outputDevicesChanged = pyqtSignal()
def _onOutputDevicesChanged(self):
for printer_output_device in self._printer_output_devices:
printer_output_device.hotendIdChanged.disconnect(self._onHotendIdChanged)
printer_output_device.materialIdChanged.disconnect(self._onMaterialIdChanged)
self._printer_output_devices.clear()
for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices():
if isinstance(printer_output_device, PrinterOutputDevice):
self._printer_output_devices.append(printer_output_device)
printer_output_device.hotendIdChanged.connect(self._onHotendIdChanged)
printer_output_device.materialIdChanged.connect(self._onMaterialIdChanged)
self.outputDevicesChanged.emit()
@pyqtProperty("QVariantList", notify = outputDevicesChanged)
def printerOutputDevices(self):
return self._printer_output_devices
def _onHotendIdChanged(self, index, hotend_id):
if not self._global_container_stack:
return
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = self._global_container_stack.getBottom().getId(), name = hotend_id)
if containers:
Logger.log("d", "Setting hotend variant of hotend %d to %s" % (index, containers[0].getId()))
ExtruderManager.ExtruderManager.getInstance().setActiveExtruderIndex(index)
self.setActiveVariant(containers[0].getId())
def _onMaterialIdChanged(self, index, material_id):
# TODO: fix this
if not self._global_container_stack:
return
definition_id = "fdmprinter"
if self._global_container_stack.getMetaDataEntry("has_machine_materials", False):
definition_id = self._global_container_stack.getBottom().getId()
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition_id, GUID = material_id)
if containers:
Logger.log("d", "Setting material of hotend %d to %s" % (index, containers[0].getId()))
ExtruderManager.ExtruderManager.getInstance().setActiveExtruderIndex(index)
self.setActiveMaterial(containers[0].getId())
else:
Logger.log("w", "No material definition found for printer definition %s and GUID %s" % (definition_id, material_id))
def _onGlobalPropertyChanged(self, key, property_name):
if property_name == "value":
self.globalValueChanged.emit()
@ -164,9 +210,6 @@ class MachineManager(QObject):
Application.getInstance().setGlobalContainerStack(new_global_stack)
@pyqtProperty("QVariantList", notify = outputDevicesChanged)
def printerOutputDevices(self):
return [printer_output_device for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices() if isinstance(printer_output_device, PrinterOutputDevice)]
## Create a name that is not empty and unique
# \param container_type \type{string} Type of the container (machine, quality, ...)
@ -235,6 +278,13 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify = activeStackChanged)
def activeStackId(self):
if self._active_container_stack:
return self._active_container_stack.getId()
return ""
@pyqtProperty(str, notify = activeMaterialChanged)
def activeMaterialName(self):
if self._active_container_stack:

View file

@ -65,10 +65,15 @@ message GCodeLayer {
bytes data = 2;
}
message ObjectPrintTime { // The print time for the whole print and material estimates for the first extruder
message PrintTimeMaterialEstimates { // The print time for the whole print and material estimates for the extruder
float time = 1; // Total time estimate
repeated MaterialEstimates materialEstimates = 2; // materialEstimates data
}
message MaterialEstimates {
int64 id = 1;
float time = 2; // Total time estimate
float material_amount = 3; // material used in the first extruder
float material_amount = 2; // material used in the extruder
}
message SettingList {

View file

@ -79,7 +79,8 @@ class CuraEngineBackend(Backend):
self._message_handlers["cura.proto.Progress"] = self._onProgressMessage
self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage
self._message_handlers["cura.proto.GCodePrefix"] = self._onGCodePrefixMessage
self._message_handlers["cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage
self._message_handlers["cura.proto.PrintTimeMaterialEstimates"] = self._onPrintTimeMaterialEstimates
#self._message_handlers["cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage
self._message_handlers["cura.proto.SlicingFinished"] = self._onSlicingFinishedMessage
self._start_slice_job = None
@ -126,11 +127,15 @@ class CuraEngineBackend(Backend):
## Perform a slice of the scene.
def slice(self):
self._stored_layer_data = []
if not self._enabled or not self._global_container_stack: #We shouldn't be slicing.
# try again in a short time
self._change_timer.start()
return
self.printDurationMessage.emit(0, [0])
self._stored_layer_data = []
if self._slicing: #We were already slicing. Stop the old job.
self._terminate()
@ -294,9 +299,12 @@ class CuraEngineBackend(Backend):
## Called when a print time message is received from the engine.
#
# \param message The protobuf message containing the print time and
# material amount.
def _onObjectPrintTimeMessage(self, message):
self.printDurationMessage.emit(message.time, message.material_amount)
# material amount per extruder
def _onPrintTimeMaterialEstimates(self, message):
material_amounts = []
for index in range(message.repeatedMessageCount("materialEstimates")):
material_amounts.append(message.getRepeatedMessage("materialEstimates", index).material_amount)
self.printDurationMessage.emit(message.time, material_amounts)
## Creates a new socket connection.
def _createSocket(self):
@ -383,4 +391,4 @@ class CuraEngineBackend(Backend):
if self._active_extruder_stack:
self._active_extruder_stack.propertyChanged.connect(self._onSettingChanged) # Note: Only starts slicing when the value changed.
self._active_extruder_stack.containersChanged.connect(self._onChanged)
self._onChanged()

View file

@ -22,7 +22,7 @@ class GCodeProfileReader(ProfileReader):
# It can only read settings with the same version as the version it was
# written with. If the file format is changed in a way that breaks reverse
# compatibility, increment this version number!
version = 1
version = 2
## Dictionary that defines how characters are escaped when embedded in
# g-code.
@ -73,18 +73,14 @@ class GCodeProfileReader(ProfileReader):
serialized = pattern.sub(lambda m: GCodeProfileReader.escape_characters[re.escape(m.group(0))], serialized)
Logger.log("i", "Serialized the following from %s: %s" %(file_name, repr(serialized)))
# Create an empty profile - the id will be changed later
# Create an empty profile - the id and name will be changed by the ContainerRegistry
profile = InstanceContainer("")
profile.addMetaDataEntry("type", "quality")
try:
profile.deserialize(serialized)
except Exception as e: # Not a valid g-code file.
Logger.log("e", "Unable to serialise the profile: %s", str(e))
return None
#Creating a unique name using the filename of the GCode
new_name = catalog.i18nc("@label", "Custom profile (%s)") %(os.path.splitext(os.path.basename(file_name))[0])
profile.setName(new_name)
profile._id = new_name
profile.addMetaDataEntry("type", "quality")
return profile

View file

@ -23,7 +23,7 @@ class GCodeWriter(MeshWriter):
# It can only read settings with the same version as the version it was
# written with. If the file format is changed in a way that breaks reverse
# compatibility, increment this version number!
version = 1
version = 2
## Dictionary that defines how characters are escaped when embedded in
# g-code.
@ -68,23 +68,21 @@ class GCodeWriter(MeshWriter):
prefix = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line.
prefix_length = len(prefix)
all_settings = InstanceContainer("G-code-imported-profile") #Create a new 'profile' with ALL settings so that the slice can be precisely reproduced.
all_settings.setDefinition(settings.getBottom())
for key in settings.getAllKeys():
all_settings.setProperty(key, "value", settings.getProperty(key, "value")) #Just copy everything over to the setting instance.
serialised = all_settings.serialize()
global_stack = Application.getInstance().getGlobalContainerStack()
container_with_profile = global_stack.findContainer({"type": "quality"})
serialized = container_with_profile.serialize()
# Escape characters that have a special meaning in g-code comments.
pattern = re.compile("|".join(GCodeWriter.escape_characters.keys()))
# Perform the replacement with a regular expression.
serialised = pattern.sub(lambda m: GCodeWriter.escape_characters[re.escape(m.group(0))], serialised)
serialized = pattern.sub(lambda m: GCodeWriter.escape_characters[re.escape(m.group(0))], serialized)
# Introduce line breaks so that each comment is no longer than 80 characters. Prepend each line with the prefix.
result = ""
# Lines have 80 characters, so the payload of each line is 80 - prefix.
for pos in range(0, len(serialised), 80 - prefix_length):
result += prefix + serialised[pos : pos + 80 - prefix_length] + "\n"
serialised = result
for pos in range(0, len(serialized), 80 - prefix_length):
result += prefix + serialized[pos : pos + 80 - prefix_length] + "\n"
serialized = result
return serialised
return serialized

View file

@ -45,6 +45,7 @@ class SliceInfo(Extension):
Preferences.getInstance().setValue("info/asked_send_slice_info", True)
def _onWriteStarted(self, output_device):
try:
if not Preferences.getInstance().getValue("info/send_slice_info"):
Logger.log("d", "'info/send_slice_info' is turned off.")
return # Do nothing, user does not want to send data
@ -54,7 +55,9 @@ class SliceInfo(Extension):
# Get total material used (in mm^3)
print_information = Application.getInstance().getPrintInformation()
material_radius = 0.5 * global_container_stack.getProperty("material_diameter", "value")
material_used = math.pi * material_radius * material_radius * print_information.materialAmount #Volume of material used
# TODO: Send material per extruder instead of mashing it on a pile
material_used = math.pi * material_radius * material_radius * sum(print_information.materialAmounts) #Volume of all materials used
# Get model information (bounding boxes, hashes and transformation matrix)
models_info = []
@ -113,4 +116,8 @@ class SliceInfo(Extension):
Logger.log("i", "Sent anonymous slice info to %s", self.info_url)
f.close()
except Exception as e:
Logger.logException("e", e)
Logger.logException("e", "An exception occurred while trying to send slice information")
except:
# We really can't afford to have a mistake here, as this would break the sending of g-code to a device
# (Either saving or directly to a printer). The functionality of the slice data is not *that* important.
pass

View file

@ -41,10 +41,6 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
self._check_updates = True
self._firmware_view = None
## Add menu item to top menu of the application.
self.setMenuName(i18n_catalog.i18nc("@title:menu","Firmware"))
self.addMenuItem(i18n_catalog.i18nc("@item:inmenu", "Update Firmware"), self.updateAllFirmware)
Application.getInstance().applicationShuttingDown.connect(self.stop)
self.addUSBOutputDeviceSignal.connect(self.addOutputDevice) #Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
@ -156,7 +152,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
"ultimaker_original_plus" : "MarlinUltimaker-UMOP-{baudrate}.hex",
"ultimaker2" : "MarlinUltimaker2.hex",
"ultimaker2_go" : "MarlinUltimaker2go.hex",
"ultimaker2plus" : "MarlinUltimaker2plus.hex",
"ultimaker2_plus" : "MarlinUltimaker2plus.hex",
"ultimaker2_extended" : "MarlinUltimaker2extended.hex",
"ultimaker2_extended_plus" : "MarlinUltimaker2extended-plus.hex",
}

View file

@ -43,7 +43,6 @@ class UMOCheckupMachineAction(MachineAction):
if self._output_device is None and self._check_started:
self.startCheck()
def _getPrinterOutputDevices(self):
return [printer_output_device for printer_output_device in
Application.getInstance().getOutputDeviceManager().getOutputDevices() if
@ -63,6 +62,7 @@ class UMOCheckupMachineAction(MachineAction):
self._output_device = None
self._check_started = False
self.checkStartedChanged.emit()
# Ensure everything is reset (and right signals are emitted again)
self._bed_test_completed = False
@ -137,9 +137,16 @@ class UMOCheckupMachineAction(MachineAction):
self._z_min_endstop_test_completed = True
self.onZMinEndstopTestCompleted.emit()
checkStartedChanged = pyqtSignal()
@pyqtProperty(bool, notify = checkStartedChanged)
def checkStarted(self):
return self._check_started
@pyqtSlot()
def startCheck(self):
self._check_started = True
self.checkStartedChanged.emit()
output_devices = self._getPrinterOutputDevices()
if output_devices:
self._output_device = output_devices[0]

View file

@ -32,7 +32,7 @@ Cura.MachineAction
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
wrapMode: Text.WordWrap
text: catalog.i18nc("@label","It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional");
text: catalog.i18nc("@label", "It's a good idea to do a few sanity checks on your Ultimaker. You can skip this step if you know your machine is functional");
}
Item
@ -51,7 +51,6 @@ Cura.MachineAction
text: catalog.i18nc("@action:button","Start Printer Check");
onClicked:
{
checkupContent.visible = true
manager.startCheck()
}
}
@ -73,7 +72,7 @@ Cura.MachineAction
id: checkupContent
anchors.top: startStopButtons.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
visible: false
visible: manager.checkStarted
width: parent.width
height: 250
//////////////////////////////////////////////////////////
@ -157,6 +156,7 @@ Cura.MachineAction
{
id: nozzleTempLabel
width: checkupMachineAction.leftRow
height: nozzleTempButton.height
anchors.left: parent.left
anchors.top: endstopZLabel.bottom
wrapMode: Text.WordWrap
@ -175,20 +175,16 @@ Cura.MachineAction
{
id: nozzleTempButton
width: checkupMachineAction.rightRow * 0.3
height: nozzleTemp.height
height: childrenRect.height
anchors.top: nozzleTempLabel.top
anchors.left: bedTempStatus.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
Button
{
height: nozzleTemp.height - 2
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
text: catalog.i18nc("@action:button","Start Heating")
onClicked:
{
manager.heatupHotend()
nozzleTempStatus.text = catalog.i18nc("@info:progress","Checking")
}
}
}
@ -208,10 +204,11 @@ Cura.MachineAction
{
id: bedTempLabel
width: checkupMachineAction.leftRow
height: bedTempButton.height
anchors.left: parent.left
anchors.top: nozzleTempLabel.bottom
wrapMode: Text.WordWrap
text: catalog.i18nc("@label","bed temperature check:")
text: catalog.i18nc("@label","Bed temperature check:")
}
Label
@ -227,15 +224,12 @@ Cura.MachineAction
{
id: bedTempButton
width: checkupMachineAction.rightRow * 0.3
height: bedTemp.height
height: childrenRect.height
anchors.top: bedTempLabel.top
anchors.left: bedTempStatus.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
Button
{
height: bedTemp.height - 2
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
text: catalog.i18nc("@action:button","Start Heating")
onClicked:
{

View file

@ -15,25 +15,38 @@ Cura.MachineAction
anchors.fill: parent;
Item
{
id: bedLevelMachineAction
anchors.fill: parent;
id: upgradeSelectionMachineAction
anchors.fill: parent
UM.I18nCatalog { id: catalog; name: "cura"; }
Column
{
anchors.fill: parent;
Label
{
id: pageTitle
width: parent.width
text: catalog.i18nc("@title", "Check Printer")
wrapMode: Text.WordWrap
font.pointSize: 18;
}
Label
{
id: pageDescription
anchors.top: pageTitle.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
wrapMode: Text.WordWrap
text: catalog.i18nc("@label","Please select any upgrades made to this ultimaker original");
text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker Original");
}
CheckBox
{
anchors.top: pageDescription.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
text: catalog.i18nc("@label", "Self-built heated bed")
checked: manager.hasHeatedBed
onClicked: manager.hasHeatedBed ? manager.removeHeatedBed() : manager.addHeatedBed()
}
}
UM.I18nCatalog { id: catalog; name: "cura"; }
}
}

View file

@ -14,7 +14,7 @@
},
"overrides": {
"machine_start_gcode": { "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\nM109 S{material_print_temperature} ;Makes sure the temperature is correct before printing\n; -- end of START GCODE --" },
"machine_start_gcode": { "default_value": "; -- START GCODE --\nM104 S{material_print_temperature} ; Heat up extruder while leveling\nM800 ; Custom GCODE to fire start print procedure\nM109 S{material_print_temperature} ; Makes sure the temperature is correct before printing\n; -- end of START GCODE --" },
"machine_end_gcode": { "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" },
"machine_width": { "default_value": 210 },
"machine_depth": { "default_value": 297 },

View file

@ -410,7 +410,7 @@
},
"skin_line_width":
{
"label": "Top/bottom Line Width",
"label": "Top/Bottom Line Width",
"description": "Width of a single top/bottom line.",
"unit": "mm",
"minimum_value": "0.0001",
@ -926,7 +926,8 @@
"description": "Retract the filament when the nozzle is moving over a non-printed area. ",
"type": "bool",
"default_value": true,
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_amount": {
"label": "Retraction Distance",
@ -937,7 +938,8 @@
"minimum_value_warning": "-0.0001",
"maximum_value_warning": "10.0",
"enabled": "retraction_enable",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_speed": {
"label": "Retraction Speed",
@ -949,7 +951,8 @@
"maximum_value": "299792458000",
"maximum_value_warning": "100",
"enabled": "retraction_enable",
"settable_per_mesh": true,
"settable_per_mesh": false,
"settable_per_extruder": true,
"children": {
"retraction_retract_speed": {
"label": "Retraction Retract Speed",
@ -962,7 +965,8 @@
"maximum_value_warning": "100",
"enabled": "retraction_enable",
"value": "retraction_speed",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_prime_speed": {
"label": "Retraction Prime Speed",
@ -975,7 +979,8 @@
"maximum_value_warning": "100",
"enabled": "retraction_enable",
"value": "retraction_speed",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
@ -988,7 +993,8 @@
"minimum_value_warning": "-0.0001",
"maximum_value_warning": "5.0",
"enabled": "retraction_enable",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_min_travel": {
"label": "Retraction Minimum Travel",
@ -1000,7 +1006,8 @@
"minimum_value": "0",
"maximum_value_warning": "10",
"enabled": "retraction_enable",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_count_max": {
"label": "Maximum Retraction Count",
@ -1010,7 +1017,8 @@
"maximum_value_warning": "100",
"type": "int",
"enabled": "retraction_enable",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_extrusion_window": {
"label": "Minimum Extrusion Distance Window",
@ -1022,7 +1030,8 @@
"maximum_value_warning": "retraction_amount * 2",
"value": "retraction_amount",
"enabled": "retraction_enable",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_hop_enabled": {
"label": "Z Hop when Retracted",
@ -1030,7 +1039,8 @@
"type": "bool",
"default_value": false,
"enabled": "retraction_enable",
"settable_per_mesh": true,
"settable_per_mesh": false,
"settable_per_extruder": true,
"children": {
"retraction_hop_only_when_collides": {
"label": "Z Hop Only Over Printed Parts",
@ -1038,7 +1048,8 @@
"type": "bool",
"default_value": false,
"enabled": "retraction_enable and retraction_hop_enabled and travel_avoid_other_parts",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_hop": {
"label": "Z Hop Height",
@ -1049,7 +1060,8 @@
"minimum_value_warning": "-0.0001",
"maximum_value_warning": "10",
"enabled": "retraction_enable and retraction_hop_enabled",
"settable_per_mesh": true
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},

View file

@ -16,7 +16,7 @@
"overrides": {
"machine_height": {
"default_value": 315
"default_value": 305
}
}
}

View file

@ -15,7 +15,7 @@
"overrides": {
"machine_height": {
"default_value": 313
"default_value": 305
},
"machine_show_variants": {
"default_value": true

View file

@ -24,7 +24,7 @@ Rectangle {
UM.I18nCatalog { id: catalog; name:"cura"}
property variant printDuration: PrintInformation.currentPrintTime
property real printMaterialAmount: PrintInformation.materialAmount
property real printMaterialAmount: PrintInformation.materialAmounts[0]
height: childrenRect.height
color: "transparent"

View file

@ -22,9 +22,9 @@ Rectangle
{
if(!printerConnected)
return UM.Theme.getColor("status_offline")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "printing")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "printing" || Cura.MachineManager.printerOutputDevices[0].jobState == "pre_print")
return UM.Theme.getColor("status_busy")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "ready")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "ready" || Cura.MachineManager.printerOutputDevices[0].jobState == "")
return UM.Theme.getColor("status_ready")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "paused")
return UM.Theme.getColor("status_paused")

View file

@ -71,10 +71,11 @@ UM.ManagementPage
elide: Text.ElideRight
}
Row
Flow
{
id: machineActions
anchors.left: parent.left
anchors.right: parent.right
anchors.top: machineName.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height

View file

@ -101,12 +101,16 @@ Rectangle
iconSource: {
if(!printerConnected)
return UM.Theme.getIcon("tab_monitor")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "printing")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "printing" || Cura.MachineManager.printerOutputDevices[0].jobState == "pre_print")
return UM.Theme.getIcon("tab_monitor_busy")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "ready" || Cura.MachineManager.printerOutputDevices[0].jobState == "")
return UM.Theme.getIcon("tab_monitor_connected")
else if(Cura.MachineManager.printerOutputDevices[0].jobState == "paused")
return UM.Theme.getIcon("tab_monitor_paused")
else if (Cura.MachineManager.printerOutputDevices[0].jobState != "error")
return UM.Theme.getIcon("tab_monitor_connected")
else if (Cura.MachineManager.printerOutputDevices[0].jobState == "error")
return UM.Theme.getIcon("tab_monitor_stopped")
else
return UM.Theme.getIcon("tab_monitor")
}
checkable: true
checked: monitoringPrint

View file

@ -15,7 +15,7 @@ Column
id: base;
property int totalHeightHeader: childrenRect.height
property int currentExtruderIndex: -1;
property int currentExtruderIndex:ExtruderManager.activeExtruderIndex;
spacing: UM.Theme.getSize("default_margin").height
@ -93,7 +93,7 @@ Column
{
base.currentExtruderIndex = -1;
forceActiveFocus()
ExtruderManager.setActiveExtruderIndex(0);
ExtruderManager.setActiveExtruderIndex(base.currentExtruderIndex);
}
}

View file

@ -371,7 +371,7 @@ Item
{
id: infillDensity
containerStackId: Cura.MachineManager.activeMachineId
containerStackId: Cura.MachineManager.activeStackId
key: "infill_sparse_density"
watchedProperties: [ "value" ]
storeIndex: 0
@ -406,6 +406,7 @@ Item
watchedProperties: [ "value" ]
storeIndex: 0
}
UM.SettingPropertyProvider
{
id: supportExtruderNr