mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-07 06:57:28 -06:00
Merge pull request #1243 from fieldOfView/feature_material_cost
Implement material cost
This commit is contained in:
commit
a8efde9450
6 changed files with 242 additions and 54 deletions
|
@ -223,6 +223,10 @@ class CuraApplication(QtApplication):
|
||||||
Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True)
|
Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True)
|
||||||
Preferences.getInstance().addPreference("cura/dialog_on_project_save", True)
|
Preferences.getInstance().addPreference("cura/dialog_on_project_save", True)
|
||||||
Preferences.getInstance().addPreference("cura/asked_dialog_on_project_save", False)
|
Preferences.getInstance().addPreference("cura/asked_dialog_on_project_save", False)
|
||||||
|
|
||||||
|
Preferences.getInstance().addPreference("cura/currency", "€")
|
||||||
|
Preferences.getInstance().addPreference("cura/material_settings", "{}")
|
||||||
|
|
||||||
for key in [
|
for key in [
|
||||||
"dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin
|
"dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin
|
||||||
"dialog_profile_path",
|
"dialog_profile_path",
|
||||||
|
|
|
@ -7,12 +7,14 @@ from UM.FlameProfiler import pyqtSlot
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Qt.Duration import Duration
|
from UM.Qt.Duration import Duration
|
||||||
from UM.Preferences import Preferences
|
from UM.Preferences import Preferences
|
||||||
|
from UM.Settings import ContainerRegistry
|
||||||
|
|
||||||
import cura.Settings.ExtruderManager
|
import cura.Settings.ExtruderManager
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import os.path
|
import os.path
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
import json
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
@ -52,6 +54,7 @@ class PrintInformation(QObject):
|
||||||
|
|
||||||
self._material_lengths = []
|
self._material_lengths = []
|
||||||
self._material_weights = []
|
self._material_weights = []
|
||||||
|
self._material_costs = []
|
||||||
|
|
||||||
self._pre_sliced = False
|
self._pre_sliced = False
|
||||||
|
|
||||||
|
@ -65,6 +68,12 @@ class PrintInformation(QObject):
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._setAbbreviatedMachineName)
|
Application.getInstance().globalContainerStackChanged.connect(self._setAbbreviatedMachineName)
|
||||||
Application.getInstance().fileLoaded.connect(self.setJobName)
|
Application.getInstance().fileLoaded.connect(self.setJobName)
|
||||||
|
|
||||||
|
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
|
||||||
|
|
||||||
|
self._active_material_container = None
|
||||||
|
Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._onActiveMaterialChanged)
|
||||||
|
self._onActiveMaterialChanged()
|
||||||
|
|
||||||
currentPrintTimeChanged = pyqtSignal()
|
currentPrintTimeChanged = pyqtSignal()
|
||||||
|
|
||||||
preSlicedChanged = pyqtSignal()
|
preSlicedChanged = pyqtSignal()
|
||||||
|
@ -93,28 +102,82 @@ class PrintInformation(QObject):
|
||||||
def materialWeights(self):
|
def materialWeights(self):
|
||||||
return self._material_weights
|
return self._material_weights
|
||||||
|
|
||||||
|
materialCostsChanged = pyqtSignal()
|
||||||
|
|
||||||
|
@pyqtProperty("QVariantList", notify = materialCostsChanged)
|
||||||
|
def materialCosts(self):
|
||||||
|
return self._material_costs
|
||||||
|
|
||||||
def _onPrintDurationMessage(self, total_time, material_amounts):
|
def _onPrintDurationMessage(self, total_time, material_amounts):
|
||||||
self._current_print_time.setDuration(total_time)
|
self._current_print_time.setDuration(total_time)
|
||||||
self.currentPrintTimeChanged.emit()
|
self.currentPrintTimeChanged.emit()
|
||||||
|
|
||||||
|
self._material_amounts = material_amounts
|
||||||
|
self._calculateInformation()
|
||||||
|
|
||||||
|
def _calculateInformation(self):
|
||||||
# Material amount is sent as an amount of mm^3, so calculate length from that
|
# Material amount is sent as an amount of mm^3, so calculate length from that
|
||||||
r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2
|
r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2
|
||||||
self._material_lengths = []
|
self._material_lengths = []
|
||||||
self._material_weights = []
|
self._material_weights = []
|
||||||
|
self._material_costs = []
|
||||||
|
|
||||||
|
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
|
||||||
|
|
||||||
extruder_stacks = list(cura.Settings.ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId()))
|
extruder_stacks = list(cura.Settings.ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId()))
|
||||||
for index, amount in enumerate(material_amounts):
|
for index, amount in enumerate(self._material_amounts):
|
||||||
## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some
|
## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some
|
||||||
# list comprehension filtering to solve this for us.
|
# list comprehension filtering to solve this for us.
|
||||||
|
material = None
|
||||||
if extruder_stacks: # Multi extrusion machine
|
if extruder_stacks: # Multi extrusion machine
|
||||||
extruder_stack = [extruder for extruder in extruder_stacks if extruder.getMetaDataEntry("position") == str(index)][0]
|
extruder_stack = [extruder for extruder in extruder_stacks if extruder.getMetaDataEntry("position") == str(index)][0]
|
||||||
density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0)
|
density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0)
|
||||||
|
material = extruder_stack.findContainer({"type": "material"})
|
||||||
else: # Machine with no extruder stacks
|
else: # Machine with no extruder stacks
|
||||||
density = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("properties", {}).get("density", 0)
|
density = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("properties", {}).get("density", 0)
|
||||||
|
material = Application.getInstance().getGlobalContainerStack().findContainer({"type": "material"})
|
||||||
|
|
||||||
self._material_weights.append(float(amount) * float(density) / 1000)
|
weight = float(amount) * float(density) / 1000
|
||||||
|
cost = 0
|
||||||
|
if material:
|
||||||
|
material_guid = material.getMetaDataEntry("GUID")
|
||||||
|
if material_guid in material_preference_values:
|
||||||
|
material_values = material_preference_values[material_guid]
|
||||||
|
|
||||||
|
weight_per_spool = float(material_values["spool_weight"] if material_values and "spool_weight" in material_values else 0)
|
||||||
|
cost_per_spool = float(material_values["spool_cost"] if material_values and "spool_cost" in material_values else 0)
|
||||||
|
|
||||||
|
if weight_per_spool != 0:
|
||||||
|
cost = cost_per_spool * weight / weight_per_spool
|
||||||
|
else:
|
||||||
|
cost = 0
|
||||||
|
|
||||||
|
self._material_weights.append(weight)
|
||||||
self._material_lengths.append(round((amount / (math.pi * r ** 2)) / 1000, 2))
|
self._material_lengths.append(round((amount / (math.pi * r ** 2)) / 1000, 2))
|
||||||
|
self._material_costs.append(cost)
|
||||||
|
|
||||||
self.materialLengthsChanged.emit()
|
self.materialLengthsChanged.emit()
|
||||||
self.materialWeightsChanged.emit()
|
self.materialWeightsChanged.emit()
|
||||||
|
self.materialCostsChanged.emit()
|
||||||
|
|
||||||
|
def _onPreferencesChanged(self, preference):
|
||||||
|
if preference != "cura/material_settings":
|
||||||
|
return
|
||||||
|
|
||||||
|
self._calculateInformation()
|
||||||
|
|
||||||
|
def _onActiveMaterialChanged(self):
|
||||||
|
if self._active_material_container:
|
||||||
|
self._active_material_container.metaDataChanged.disconnect(self._onMaterialMetaDataChanged)
|
||||||
|
|
||||||
|
active_material_id = Application.getInstance().getMachineManager().activeMaterialId
|
||||||
|
self._active_material_container = ContainerRegistry.getInstance().findInstanceContainers(id=active_material_id)[0]
|
||||||
|
|
||||||
|
if self._active_material_container:
|
||||||
|
self._active_material_container.metaDataChanged.connect(self._onMaterialMetaDataChanged)
|
||||||
|
|
||||||
|
def _onMaterialMetaDataChanged(self):
|
||||||
|
self._calculateInformation()
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def setJobName(self, name):
|
def setJobName(self, name):
|
||||||
|
|
|
@ -26,6 +26,7 @@ Rectangle {
|
||||||
property variant printDuration: PrintInformation.currentPrintTime
|
property variant printDuration: PrintInformation.currentPrintTime
|
||||||
property variant printMaterialLengths: PrintInformation.materialLengths
|
property variant printMaterialLengths: PrintInformation.materialLengths
|
||||||
property variant printMaterialWeights: PrintInformation.materialWeights
|
property variant printMaterialWeights: PrintInformation.materialWeights
|
||||||
|
property variant printMaterialCosts: PrintInformation.materialCosts
|
||||||
|
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
@ -133,7 +134,8 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label{
|
Label
|
||||||
|
{
|
||||||
id: boundingSpec
|
id: boundingSpec
|
||||||
anchors.top: jobNameRow.bottom
|
anchors.top: jobNameRow.bottom
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
@ -144,17 +146,20 @@ Rectangle {
|
||||||
text: Printer.getSceneBoundingBoxString
|
text: Printer.getSceneBoundingBoxString
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle
|
||||||
|
{
|
||||||
id: specsRow
|
id: specsRow
|
||||||
anchors.top: boundingSpec.bottom
|
anchors.top: boundingSpec.bottom
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
height: UM.Theme.getSize("jobspecs_line").height
|
height: UM.Theme.getSize("jobspecs_line").height
|
||||||
|
|
||||||
Item{
|
Item
|
||||||
|
{
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height
|
height: parent.height
|
||||||
|
|
||||||
UM.RecolorImage {
|
UM.RecolorImage
|
||||||
|
{
|
||||||
id: timeIcon
|
id: timeIcon
|
||||||
anchors.right: timeSpec.left
|
anchors.right: timeSpec.left
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
|
||||||
|
@ -166,7 +171,8 @@ Rectangle {
|
||||||
color: UM.Theme.getColor("text_subtext")
|
color: UM.Theme.getColor("text_subtext")
|
||||||
source: UM.Theme.getIcon("print_time")
|
source: UM.Theme.getIcon("print_time")
|
||||||
}
|
}
|
||||||
Label{
|
Label
|
||||||
|
{
|
||||||
id: timeSpec
|
id: timeSpec
|
||||||
anchors.right: lengthIcon.left
|
anchors.right: lengthIcon.left
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
@ -175,7 +181,8 @@ Rectangle {
|
||||||
color: UM.Theme.getColor("text_subtext")
|
color: UM.Theme.getColor("text_subtext")
|
||||||
text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
|
text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
|
||||||
}
|
}
|
||||||
UM.RecolorImage {
|
UM.RecolorImage
|
||||||
|
{
|
||||||
id: lengthIcon
|
id: lengthIcon
|
||||||
anchors.right: lengthSpec.left
|
anchors.right: lengthSpec.left
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
|
||||||
|
@ -187,7 +194,8 @@ Rectangle {
|
||||||
color: UM.Theme.getColor("text_subtext")
|
color: UM.Theme.getColor("text_subtext")
|
||||||
source: UM.Theme.getIcon("category_material")
|
source: UM.Theme.getIcon("category_material")
|
||||||
}
|
}
|
||||||
Label{
|
Label
|
||||||
|
{
|
||||||
id: lengthSpec
|
id: lengthSpec
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
@ -197,21 +205,40 @@ Rectangle {
|
||||||
{
|
{
|
||||||
var lengths = [];
|
var lengths = [];
|
||||||
var weights = [];
|
var weights = [];
|
||||||
|
var costs = [];
|
||||||
|
var someCostsKnown = false;
|
||||||
if(base.printMaterialLengths) {
|
if(base.printMaterialLengths) {
|
||||||
for(var index = 0; index < base.printMaterialLengths.length; index++) {
|
for(var index = 0; index < base.printMaterialLengths.length; index++)
|
||||||
if(base.printMaterialLengths[index] > 0) {
|
{
|
||||||
|
if(base.printMaterialLengths[index] > 0)
|
||||||
|
{
|
||||||
lengths.push(base.printMaterialLengths[index].toFixed(2));
|
lengths.push(base.printMaterialLengths[index].toFixed(2));
|
||||||
weights.push(String(Math.floor(base.printMaterialWeights[index])));
|
weights.push(String(Math.floor(base.printMaterialWeights[index])));
|
||||||
|
costs.push(base.printMaterialCosts[index].toFixed(2));
|
||||||
|
if(base.printMaterialCosts[index] > 0)
|
||||||
|
{
|
||||||
|
someCostsKnown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(lengths.length == 0) {
|
}
|
||||||
|
if(lengths.length == 0)
|
||||||
|
{
|
||||||
lengths = ["0.00"];
|
lengths = ["0.00"];
|
||||||
weights = ["0"];
|
weights = ["0"];
|
||||||
|
costs = ["0.00"];
|
||||||
}
|
}
|
||||||
|
if(someCostsKnown)
|
||||||
|
{
|
||||||
|
return catalog.i18nc("@label", "%1 m / ~ %2 g / ~ %4 %3").arg(lengths.join(" + "))
|
||||||
|
.arg(weights.join(" + ")).arg(costs.join(" + ")).arg(UM.Preferences.getValue("cura/currency"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return catalog.i18nc("@label", "%1 m / ~ %2 g").arg(lengths.join(" + ")).arg(weights.join(" + "));
|
return catalog.i18nc("@label", "%1 m / ~ %2 g").arg(lengths.join(" + ")).arg(weights.join(" + "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,19 @@ UM.PreferencesPage
|
||||||
currentIndex -= 1;
|
currentIndex -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: currencyLabel
|
||||||
|
text: catalog.i18nc("@label","Currency:")
|
||||||
|
anchors.verticalCenter: languageComboBox.verticalCenter
|
||||||
|
}
|
||||||
|
TextField
|
||||||
|
{
|
||||||
|
id: currencyField
|
||||||
|
text: UM.Preferences.getValue("cura/currency")
|
||||||
|
onTextChanged: UM.Preferences.setValue("cura/currency", text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Label
|
Label
|
||||||
|
|
|
@ -15,14 +15,19 @@ TabView
|
||||||
property QtObject properties;
|
property QtObject properties;
|
||||||
|
|
||||||
property bool editingEnabled: false;
|
property bool editingEnabled: false;
|
||||||
property string currency: UM.Preferences.getValue("general/currency") ? UM.Preferences.getValue("general/currency") : "€"
|
property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€"
|
||||||
property real firstColumnWidth: width * 0.45
|
property real firstColumnWidth: width * 0.45
|
||||||
property real secondColumnWidth: width * 0.45
|
property real secondColumnWidth: width * 0.45
|
||||||
property string containerId: ""
|
property string containerId: ""
|
||||||
|
property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {}
|
||||||
|
|
||||||
|
property double spoolLength: calculateSpoolLength()
|
||||||
|
property real costPerMeter: calculateCostPerMeter()
|
||||||
|
|
||||||
Tab
|
Tab
|
||||||
{
|
{
|
||||||
title: catalog.i18nc("@title","Information")
|
title: catalog.i18nc("@title","Information")
|
||||||
|
|
||||||
anchors
|
anchors
|
||||||
{
|
{
|
||||||
leftMargin: UM.Theme.getSize("default_margin").width
|
leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
|
@ -35,6 +40,7 @@ TabView
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
|
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
|
||||||
|
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||||
|
|
||||||
Flow
|
Flow
|
||||||
{
|
{
|
||||||
|
@ -112,64 +118,78 @@ TabView
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
|
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
|
||||||
ReadOnlySpinBox
|
ReadOnlySpinBox
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
id: densitySpinBox
|
||||||
value: properties.density;
|
width: base.secondColumnWidth
|
||||||
|
value: properties.density
|
||||||
decimals: 2
|
decimals: 2
|
||||||
suffix: "g/cm³"
|
suffix: " g/cm³"
|
||||||
stepSize: 0.01
|
stepSize: 0.01
|
||||||
readOnly: !base.editingEnabled;
|
readOnly: !base.editingEnabled
|
||||||
|
|
||||||
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
|
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
|
||||||
|
onValueChanged: updateCostPerMeter()
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
|
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
|
||||||
ReadOnlySpinBox
|
ReadOnlySpinBox
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
id: diameterSpinBox
|
||||||
value: properties.diameter;
|
width: base.secondColumnWidth
|
||||||
|
value: properties.diameter
|
||||||
decimals: 2
|
decimals: 2
|
||||||
suffix: "mm"
|
suffix: " mm"
|
||||||
stepSize: 0.01
|
stepSize: 0.01
|
||||||
readOnly: !base.editingEnabled;
|
readOnly: !base.editingEnabled
|
||||||
|
|
||||||
onEditingFinished: base.setMetaDataEntry("properties/diameter", properties.diameter, value)
|
onEditingFinished: base.setMetaDataEntry("properties/diameter", properties.diameter, value)
|
||||||
|
onValueChanged: updateCostPerMeter()
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
|
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
|
||||||
SpinBox
|
SpinBox
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
id: spoolCostSpinBox
|
||||||
value: properties.spool_cost;
|
width: base.secondColumnWidth
|
||||||
prefix: base.currency
|
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
|
||||||
enabled: false
|
prefix: base.currency + " "
|
||||||
|
decimals: 2
|
||||||
|
maximumValue: 1000
|
||||||
|
|
||||||
|
onEditingFinished: base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
|
||||||
|
onValueChanged: updateCostPerMeter()
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
|
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
|
||||||
SpinBox
|
SpinBox
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
id: spoolWeightSpinBox
|
||||||
value: properties.spool_weight;
|
width: base.secondColumnWidth
|
||||||
suffix: "g";
|
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight")
|
||||||
stepSize: 10
|
suffix: " g"
|
||||||
enabled: false
|
stepSize: 100
|
||||||
|
decimals: 0
|
||||||
|
maximumValue: 10000
|
||||||
|
|
||||||
|
onEditingFinished: base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
|
||||||
|
onValueChanged: updateCostPerMeter()
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
|
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
|
||||||
SpinBox
|
Label
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
width: base.secondColumnWidth
|
||||||
value: parseFloat(properties.spool_length);
|
text: "~ %1 m".arg(Math.round(base.spoolLength))
|
||||||
suffix: "m";
|
verticalAlignment: Qt.AlignVCenter
|
||||||
enabled: false
|
height: parent.rowHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter (Approx.)") }
|
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
|
||||||
SpinBox
|
Label
|
||||||
{
|
{
|
||||||
width: base.secondColumnWidth;
|
width: base.secondColumnWidth
|
||||||
value: parseFloat(properties.cost_per_meter);
|
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
|
||||||
suffix: catalog.i18nc("@label", "%1/m".arg(base.currency));
|
verticalAlignment: Qt.AlignVCenter
|
||||||
enabled: false
|
height: parent.rowHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
||||||
|
@ -200,6 +220,12 @@ TabView
|
||||||
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
|
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateCostPerMeter()
|
||||||
|
{
|
||||||
|
base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
|
||||||
|
base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +285,44 @@ TabView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function calculateSpoolLength(diameter, density, spoolWeight)
|
||||||
|
{
|
||||||
|
if(!diameter)
|
||||||
|
{
|
||||||
|
diameter = properties.diameter;
|
||||||
|
}
|
||||||
|
if(!density)
|
||||||
|
{
|
||||||
|
density = properties.density;
|
||||||
|
}
|
||||||
|
if(!spoolWeight)
|
||||||
|
{
|
||||||
|
spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diameter == 0 || density == 0 || spoolWeight == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2
|
||||||
|
var volume = (spoolWeight / density); // in cm3
|
||||||
|
return volume / area; // in m
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateCostPerMeter(spoolCost)
|
||||||
|
{
|
||||||
|
if(!spoolCost)
|
||||||
|
{
|
||||||
|
spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spoolLength == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return spoolCost / spoolLength;
|
||||||
|
}
|
||||||
|
|
||||||
// Tiny convenience function to check if a value really changed before trying to set it.
|
// Tiny convenience function to check if a value really changed before trying to set it.
|
||||||
function setMetaDataEntry(entry_name, old_value, new_value)
|
function setMetaDataEntry(entry_name, old_value, new_value)
|
||||||
{
|
{
|
||||||
|
@ -268,6 +332,32 @@ TabView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setMaterialPreferenceValue(material_guid, entry_name, new_value)
|
||||||
|
{
|
||||||
|
if(!(material_guid in materialPreferenceValues))
|
||||||
|
{
|
||||||
|
materialPreferenceValues[material_guid] = {};
|
||||||
|
}
|
||||||
|
if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value)
|
||||||
|
{
|
||||||
|
// value has not changed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
materialPreferenceValues[material_guid][entry_name] = new_value;
|
||||||
|
|
||||||
|
// store preference
|
||||||
|
UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMaterialPreferenceValue(material_guid, entry_name)
|
||||||
|
{
|
||||||
|
if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid])
|
||||||
|
{
|
||||||
|
return materialPreferenceValues[material_guid][entry_name];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
function setName(old_value, new_value)
|
function setName(old_value, new_value)
|
||||||
{
|
{
|
||||||
if(old_value != new_value)
|
if(old_value != new_value)
|
||||||
|
|
|
@ -185,17 +185,6 @@ UM.ManagementPage
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
|
||||||
Label { text: materialProperties.name; font: UM.Theme.getFont("large"); }
|
Label { text: materialProperties.name; font: UM.Theme.getFont("large"); }
|
||||||
Button
|
|
||||||
{
|
|
||||||
id: editButton
|
|
||||||
anchors.right: parent.right;
|
|
||||||
text: catalog.i18nc("@action:button", "Edit");
|
|
||||||
iconName: "document-edit";
|
|
||||||
|
|
||||||
enabled: base.currentItem != null && !base.currentItem.readOnly
|
|
||||||
|
|
||||||
checkable: enabled
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialView
|
MaterialView
|
||||||
|
@ -209,7 +198,7 @@ UM.ManagementPage
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
editingEnabled: editButton.checkable && editButton.checked;
|
editingEnabled: base.currentItem != null && !base.currentItem.readOnly
|
||||||
|
|
||||||
properties: materialProperties
|
properties: materialProperties
|
||||||
containerId: base.currentItem != null ? base.currentItem.id : ""
|
containerId: base.currentItem != null ? base.currentItem.id : ""
|
||||||
|
@ -219,6 +208,7 @@ UM.ManagementPage
|
||||||
{
|
{
|
||||||
id: materialProperties
|
id: materialProperties
|
||||||
|
|
||||||
|
property string guid: "00000000-0000-0000-0000-000000000000"
|
||||||
property string name: "Unknown";
|
property string name: "Unknown";
|
||||||
property string profile_type: "Unknown";
|
property string profile_type: "Unknown";
|
||||||
property string supplier: "Unknown";
|
property string supplier: "Unknown";
|
||||||
|
@ -344,6 +334,7 @@ UM.ManagementPage
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
materialProperties.name = currentItem.name;
|
materialProperties.name = currentItem.name;
|
||||||
|
materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID");
|
||||||
|
|
||||||
if(currentItem.metadata != undefined && currentItem.metadata != null)
|
if(currentItem.metadata != undefined && currentItem.metadata != null)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue