diff --git a/conandata.yml b/conandata.yml index 6bec3ee231..de95766ed2 100644 --- a/conandata.yml +++ b/conandata.yml @@ -5,7 +5,7 @@ requirements: - "curaengine/5.10.0-alpha.0@ultimaker/testing" - "cura_binary_data/5.10.0-alpha.0@ultimaker/testing" - "fdm_materials/5.10.0-alpha.0@ultimaker/testing" - - "dulcificum/0.2.1@ultimaker/stable" + - "dulcificum/0.3.0@ultimaker/stable" - "pysavitar/5.4.0-alpha.0@ultimaker/stable" - "pynest2d/5.4.0-alpha.0@ultimaker/stable" requirements_internal: diff --git a/cura/PrinterOutput/Models/PrinterConfigurationModel.py b/cura/PrinterOutput/Models/PrinterConfigurationModel.py index 85c69abcd3..d42be47b41 100644 --- a/cura/PrinterOutput/Models/PrinterConfigurationModel.py +++ b/cura/PrinterOutput/Models/PrinterConfigurationModel.py @@ -1,9 +1,12 @@ -# Copyright (c) 2018 Ultimaker B.V. +# Copyright (c) 2025 UltiMaker # Cura is released under the terms of the LGPLv3 or higher. from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal from typing import List +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.DefinitionContainer import DefinitionContainer + MYPY = False if MYPY: from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel @@ -68,6 +71,15 @@ class PrinterConfigurationModel(QObject): return True return False + @pyqtProperty("QStringList", constant=True) + def validCoresForPrinterType(self) -> List[str]: + printers = ContainerRegistry.getInstance().findContainersMetadata( + ignore_case=True, type="machine", name=self._printer_type, container_type=DefinitionContainer) + id = printers[0]["id"] if len(printers) > 0 and "id" in printers[0] else "" + definitions = ContainerRegistry.getInstance().findContainersMetadata( + ignore_case=True, type="variant", definition=id+"*") + return [x["name"] for x in definitions] + def __str__(self): message_chunks = [] message_chunks.append("Printer type: " + self._printer_type) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 82b52d3dde..4c16061074 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1678,7 +1678,7 @@ class MachineManager(QObject): intent_category = self.activeIntentCategory, intent_name = IntentCategoryModel.translation(self.activeIntentCategory, "name", self.activeIntentCategory.title()), custom_profile = self.activeQualityOrQualityChangesName if global_stack.qualityChanges is not empty_quality_changes_container else None, - layer_height = self.activeQualityLayerHeight if self.isActiveQualitySupported else None, + layer_height = float("{:.2f}".format(self.activeQualityLayerHeight)) if self.isActiveQualitySupported else None, is_experimental = self.isActiveQualityExperimental and self.isActiveQualitySupported ) diff --git a/plugins/MakerbotWriter/MakerbotWriter.py b/plugins/MakerbotWriter/MakerbotWriter.py index 5c655dc8cc..f35b53a84d 100644 --- a/plugins/MakerbotWriter/MakerbotWriter.py +++ b/plugins/MakerbotWriter/MakerbotWriter.py @@ -46,6 +46,13 @@ class MakerbotWriter(MeshWriter): suffixes=["makerbot"] ) ) + MimeTypeDatabase.addMimeType( + MimeType( + name="application/x-makerbot-replicator_plus", + comment="Makerbot Toolpath Package", + suffixes=["makerbot"] + ) + ) _PNG_FORMAT = [ {"prefix": "isometric_thumbnail", "width": 120, "height": 120}, @@ -114,6 +121,8 @@ class MakerbotWriter(MeshWriter): filename, filedata = "print.gcode", gcode_text_io.getvalue() case "application/x-makerbot": filename, filedata = "print.jsontoolpath", du.gcode_2_miracle_jtp(gcode_text_io.getvalue()) + case "application/x-makerbot-replicator_plus": + filename, filedata = "print.jsontoolpath", du.gcode_2_miracle_jtp(gcode_text_io.getvalue(), nb_extruders=1) case _: raise Exception("Unsupported Mime type") diff --git a/plugins/MakerbotWriter/__init__.py b/plugins/MakerbotWriter/__init__.py index 60f232fbc0..bd766add8e 100644 --- a/plugins/MakerbotWriter/__init__.py +++ b/plugins/MakerbotWriter/__init__.py @@ -25,6 +25,12 @@ def getMetaData(): "description": catalog.i18nc("@item:inlistbox", "Makerbot Sketch Printfile"), "mime_type": "application/x-makerbot-sketch", "mode": MakerbotWriter.MakerbotWriter.OutputMode.BinaryMode, + }, + { + "extension": file_extension, + "description": catalog.i18nc("@item:inlistbox", "Makerbot Replicator+ Printfile"), + "mime_type": "application/x-makerbot-replicator_plus", + "mode": MakerbotWriter.MakerbotWriter.OutputMode.BinaryMode, } ] }, diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 85b98e532b..18d9466eb5 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -97,6 +97,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice): CuraApplication.getInstance().getOnExitCallbackManager().addCallback(self._checkActivePrintingUponAppExit) + CuraApplication.getInstance().getPreferences().addPreference("usb_printing/enabled", False) + # This is a callback function that checks if there is any printing in progress via USB when the application tries # to exit. If so, it will show a confirmation before def _checkActivePrintingUponAppExit(self) -> None: @@ -144,6 +146,8 @@ class USBPrinterOutputDevice(PrinterOutputDevice): CuraApplication.getInstance().getController().setActiveStage("MonitorStage") + CuraApplication.getInstance().getPreferences().setValue("usb_printing/enabled", True) + #Find the g-code to print. gcode_textio = StringIO() gcode_writer = cast(MeshWriter, PluginRegistry.getInstance().getPluginObject("GCodeWriter")) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 04cef16f86..5fe351487c 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3232,6 +3232,19 @@ "minimum_value": 0.01, "settable_per_mesh": false, "settable_per_extruder": true + }, + "material_pressure_advance_factor": + { + "enabled": false, + "label": "Pressure advance factor", + "description": "Tuning factor for pressure advance, which is meant to synchronize extrusion with motion", + "default_value": 0.05, + "maximum_value_warning": 1.0, + "minimum_value": 0, + "type": "float", + "settable_per_mesh": false, + "settable_per_extruder": true, + "settable_per_meshgroup": false } } }, diff --git a/resources/definitions/sovol_base_bowden.def.json b/resources/definitions/sovol_base_bowden.def.json index 670b24fffc..0f389a25f8 100644 --- a/resources/definitions/sovol_base_bowden.def.json +++ b/resources/definitions/sovol_base_bowden.def.json @@ -10,6 +10,6 @@ "overrides": { "retraction_amount": { "default_value": 5 }, - "retraction_speed": { "value": "machine_max_feedrate_e" } + "retraction_speed": { "value": "resolveOrValue('machine_max_feedrate_e')" } } } \ No newline at end of file diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml index bcbb6d7679..f76e1c6ef7 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationItem.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Ultimaker B.V. +// Copyright (c) 2025 UltiMaker // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 @@ -12,7 +12,7 @@ Button id: configurationItem property var configuration: null - hoverEnabled: isValidMaterial + hoverEnabled: isValidMaterial && isValidCore property bool isValidMaterial: { @@ -25,7 +25,6 @@ Button for (var index in extruderConfigurations) { var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" - if (name == "" || name == "Unknown") { return false @@ -34,6 +33,25 @@ Button return true } + property bool isValidCore: + { + if (configuration === null) + { + return false + } + var extruderConfigurations = configuration.extruderConfigurations + var coresList = configuration.validCoresForPrinterType + for (var index in extruderConfigurations) + { + var name = extruderConfigurations[index].hotendID ? extruderConfigurations[index].hotendID : "" + if (name != "" && ! coresList.includes(name)) + { + return false + } + } + return true + } + background: Rectangle { color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") @@ -60,7 +78,7 @@ Button right: parent.right rightMargin: UM.Theme.getSize("wide_margin").width } - height: childrenRect.height + height: unknownMaterial.visible ? unknownMaterial.height : (repeater.count > 0 ? repeater.itemAt(0).height : 0) spacing: UM.Theme.getSize("default_margin").width Repeater @@ -72,21 +90,20 @@ Button { width: Math.round(parent.width / (configuration !== null ? configuration.extruderConfigurations.length : 1)) printCoreConfiguration: modelData - visible: configurationItem.isValidMaterial + visible: configurationItem.isValidMaterial && configurationItem.isValidCore } } - // Unknown material + // Unknown material or core ('variant') Item { id: unknownMaterial - height: unknownMaterialMessage.height + UM.Theme.getSize("thin_margin").width / 2 + height: unknownMaterialMessage.height width: parent.width anchors.top: parent.top - anchors.topMargin: UM.Theme.getSize("thin_margin").width / 2 - visible: !configurationItem.isValidMaterial + visible: ! (configurationItem.isValidMaterial && configurationItem.isValidCore) UM.ColorImage { @@ -102,13 +119,9 @@ Button UM.Label { id: unknownMaterialMessage - text: - { - if (configuration === null) - { - return "" - } + function whenUnknownMaterial() + { var extruderConfigurations = configuration.extruderConfigurations var unknownMaterials = [] for (var index in extruderConfigurations) @@ -135,9 +148,47 @@ Button unknownMaterials = "" + unknownMaterials + "" var draftResult = catalog.i18nc("@label", "This configuration is not available because %1 is not recognized. Please visit %2 to download the correct material profile."); - var result = draftResult.arg(unknownMaterials).arg("" + catalog.i18nc("@label","Marketplace") + " ") + return draftResult.arg(unknownMaterials).arg("" + catalog.i18nc("@label","Marketplace") + " ") + } - return result + function whenMismatchedCore() + { + var extruderConfigurations = configuration.extruderConfigurations + var coresList = configuration.validCoresForPrinterType + var mismatchedCores = [] + for (var index in extruderConfigurations) + { + var name = extruderConfigurations[index].hotendID ? extruderConfigurations[index].hotendID : "" + if (name != "" && ! coresList.includes(name)) + { + mismatchedCores.push(name) + } + } + + mismatchedCores = "" + mismatchedCores + "" + var draftResult = catalog.i18nc("@label", "This configuration is not available because there is a mismatch or other problem with core-type %1. Please visit %2 to check which cores this printer-type supports w.r.t. new slices."); + return draftResult.arg(mismatchedCores).arg("" + catalog.i18nc("@label","WEBSITE") + " ") + } + + text: + { + if (configuration === null) + { + return "" + } + + var extruderConfigurations = configuration.extruderConfigurations + var perExtruder = [] + for (var index in extruderConfigurations) + { + var matName = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" + var coreName = extruderConfigurations[index].hotendID ? extruderConfigurations[index].hotendID : "" + perExtruder.push(` [${coreName}/${matName}]`) + } + + var configsStr = "" + perExtruder + "" + var warnStr = isValidMaterial ? whenMismatchedCore() : whenUnknownMaterial() + return configsStr + "
" + warnStr } width: extruderRow.width @@ -225,7 +276,7 @@ Button onClicked: { - if(isValidMaterial) + if (isValidMaterial && isValidCore) { toggleContent() Cura.MachineManager.applyRemoteConfiguration(configuration) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 1d8ad654e3..f46c59ff61 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -13,7 +13,7 @@ import "." Item { id: base - height: enabled ? UM.Theme.getSize("section").height + UM.Theme.getSize("narrow_margin").height : 0 + height: enabled ? Math.max(UM.Theme.getSize("section").height, label.height) + UM.Theme.getSize("narrow_margin").height : 0 anchors.left: parent.left anchors.right: parent.right diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 160799be6e..1ae316f96c 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -567,7 +567,7 @@ "section_icon_column": [2.5, 2.5], "setting": [25.0, 1.8], - "setting_control": [11.0, 2.0], + "setting_control": [9.0, 2.0], "setting_control_radius": [0.15, 0.15], "setting_control_depth_margin": [1.4, 0.0], "setting_unit_margin": [0.5, 0.5],