Merge pull request #20169 from Ultimaker/CURA-12368_mismatched_core_warning

[CURA-12368] Warn for mismatched cores on multi-config printers.
This commit is contained in:
HellAholic 2025-01-29 13:54:47 +01:00 committed by GitHub
commit 628c852054
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 82 additions and 19 deletions

View File

@ -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. # Cura is released under the terms of the LGPLv3 or higher.
from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal
from typing import List from typing import List
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.DefinitionContainer import DefinitionContainer
MYPY = False MYPY = False
if MYPY: if MYPY:
from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel from cura.PrinterOutput.Models.ExtruderConfigurationModel import ExtruderConfigurationModel
@ -68,6 +71,15 @@ class PrinterConfigurationModel(QObject):
return True return True
return False 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): def __str__(self):
message_chunks = [] message_chunks = []
message_chunks.append("Printer type: " + self._printer_type) message_chunks.append("Printer type: " + self._printer_type)

View File

@ -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. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
@ -12,7 +12,7 @@ Button
id: configurationItem id: configurationItem
property var configuration: null property var configuration: null
hoverEnabled: isValidMaterial hoverEnabled: isValidMaterial && isValidCore
property bool isValidMaterial: property bool isValidMaterial:
{ {
@ -25,7 +25,6 @@ Button
for (var index in extruderConfigurations) for (var index in extruderConfigurations)
{ {
var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : "" var name = extruderConfigurations[index].material ? extruderConfigurations[index].material.name : ""
if (name == "" || name == "Unknown") if (name == "" || name == "Unknown")
{ {
return false return false
@ -34,6 +33,25 @@ Button
return true 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 background: Rectangle
{ {
color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button") color: parent.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
@ -60,7 +78,7 @@ Button
right: parent.right right: parent.right
rightMargin: UM.Theme.getSize("wide_margin").width 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 spacing: UM.Theme.getSize("default_margin").width
Repeater Repeater
@ -72,21 +90,20 @@ Button
{ {
width: Math.round(parent.width / (configuration !== null ? configuration.extruderConfigurations.length : 1)) width: Math.round(parent.width / (configuration !== null ? configuration.extruderConfigurations.length : 1))
printCoreConfiguration: modelData printCoreConfiguration: modelData
visible: configurationItem.isValidMaterial visible: configurationItem.isValidMaterial && configurationItem.isValidCore
} }
} }
// Unknown material // Unknown material or core ('variant')
Item Item
{ {
id: unknownMaterial id: unknownMaterial
height: unknownMaterialMessage.height + UM.Theme.getSize("thin_margin").width / 2 height: unknownMaterialMessage.height
width: parent.width width: parent.width
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: UM.Theme.getSize("thin_margin").width / 2
visible: !configurationItem.isValidMaterial visible: ! (configurationItem.isValidMaterial && configurationItem.isValidCore)
UM.ColorImage UM.ColorImage
{ {
@ -102,13 +119,9 @@ Button
UM.Label UM.Label
{ {
id: unknownMaterialMessage id: unknownMaterialMessage
text:
{
if (configuration === null)
{
return ""
}
function whenUnknownMaterial()
{
var extruderConfigurations = configuration.extruderConfigurations var extruderConfigurations = configuration.extruderConfigurations
var unknownMaterials = [] var unknownMaterials = []
for (var index in extruderConfigurations) for (var index in extruderConfigurations)
@ -135,9 +148,47 @@ Button
unknownMaterials = "<b>" + unknownMaterials + "</b>" unknownMaterials = "<b>" + unknownMaterials + "</b>"
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 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("<a href=' '>" + catalog.i18nc("@label","Marketplace") + "</a> ") return draftResult.arg(unknownMaterials).arg("<a href=' '>" + catalog.i18nc("@label","Marketplace") + "</a> ")
}
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 = "<b>" + mismatchedCores + "</b>"
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("<a href=' '>" + catalog.i18nc("@label","WEBSITE") + "</a> ")
}
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 = "<i>" + perExtruder + "</i>"
var warnStr = isValidMaterial ? whenMismatchedCore() : whenUnknownMaterial()
return configsStr + "<br/>" + warnStr
} }
width: extruderRow.width width: extruderRow.width
@ -225,7 +276,7 @@ Button
onClicked: onClicked:
{ {
if(isValidMaterial) if (isValidMaterial && isValidCore)
{ {
toggleContent() toggleContent()
Cura.MachineManager.applyRemoteConfiguration(configuration) Cura.MachineManager.applyRemoteConfiguration(configuration)