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],