From f15aa667510bb6ffe472fa7fd1801d060555b142 Mon Sep 17 00:00:00 2001
From: 14bitVoid <14bitvoid@protonmail.com>
Date: Fri, 5 May 2017 00:05:17 +0200
Subject: [PATCH 1/5] Receive time estimates per feature
---
cura/PrintInformation.py | 14 +++++----
plugins/CuraEngineBackend/Cura.proto | 20 +++++++++---
.../CuraEngineBackend/CuraEngineBackend.py | 31 +++++++++++++++++--
3 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py
index ab63e4034d..cd1a194254 100644
--- a/cura/PrintInformation.py
+++ b/cura/PrintInformation.py
@@ -111,12 +111,14 @@ class PrintInformation(QObject):
def materialCosts(self):
return self._material_costs
- def _onPrintDurationMessage(self, total_time, material_amounts):
- if total_time != total_time: # Check for NaN. Engine can sometimes give us weird values.
- Logger.log("w", "Received NaN for print duration message")
- self._current_print_time.setDuration(0)
- else:
- self._current_print_time.setDuration(total_time)
+ def _onPrintDurationMessage(self, time_per_feature, material_amounts):
+ total_time = 0
+ for feature, time in time_per_feature.items():
+ if time != time: # Check for NaN. Engine can sometimes give us weird values.
+ Logger.log("w", "Received NaN for print duration message")
+ continue
+ total_time += time
+ self._current_print_time.setDuration(total_time)
self.currentPrintTimeChanged.emit()
diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto
index 4eab500f0a..c2e4e5bb5f 100644
--- a/plugins/CuraEngineBackend/Cura.proto
+++ b/plugins/CuraEngineBackend/Cura.proto
@@ -90,9 +90,21 @@ message GCodeLayer {
}
-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 PrintTimeMaterialEstimates { // The print time for each feature and material estimates for the extruder
+ // Time estimate in each feature
+ float time_none = 1;
+ float time_inset_0 = 2;
+ float time_inset_x = 3;
+ float time_skin = 4;
+ float time_support = 5;
+ float time_skirt = 6;
+ float time_infill = 7;
+ float time_support_infill = 8;
+ float time_travel = 9;
+ float time_retract = 10;
+ float time_support_interface = 11;
+
+ repeated MaterialEstimates materialEstimates = 12; // materialEstimates data
}
message MaterialEstimates {
@@ -121,4 +133,4 @@ message GCodePrefix {
}
message SlicingFinished {
-}
\ No newline at end of file
+}
diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py
index f32993fd20..c13cb72864 100755
--- a/plugins/CuraEngineBackend/CuraEngineBackend.py
+++ b/plugins/CuraEngineBackend/CuraEngineBackend.py
@@ -187,7 +187,19 @@ class CuraEngineBackend(QObject, Backend):
Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.")
return
- self.printDurationMessage.emit(0, [0])
+ self.printDurationMessage.emit({
+ "none": 0,
+ "inset_0": 0,
+ "inset_x": 0,
+ "skin": 0,
+ "support": 0,
+ "skirt": 0,
+ "infill": 0,
+ "support_infill": 0,
+ "travel": 0,
+ "retract": 0,
+ "support_interface": 0
+ }, [0])
self._stored_layer_data = []
self._stored_optimized_layer_data = []
@@ -475,13 +487,26 @@ class CuraEngineBackend(QObject, Backend):
## Called when a print time message is received from the engine.
#
- # \param message The protobuff message containing the print time and
+ # \param message The protobuf message containing the print time per feature and
# 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)
+ feature_times = {
+ "none": message.time_none,
+ "inset_0": message.time_inset_0,
+ "inset_x": message.time_inset_x,
+ "skin": message.time_skin,
+ "support": message.time_support,
+ "skirt": message.time_skirt,
+ "infill": message.time_infill,
+ "support_infill": message.time_support_infill,
+ "travel": message.time_travel,
+ "retract": message.time_retract,
+ "support_interface": message.time_support_interface
+ }
+ self.printDurationMessage.emit(feature_times, material_amounts)
## Creates a new socket connection.
def _createSocket(self):
From 69a95e37a5ec05ca63321abe8acf53283ea49350 Mon Sep 17 00:00:00 2001
From: 14bitVoid <14bitvoid@protonmail.com>
Date: Fri, 5 May 2017 01:34:09 +0200
Subject: [PATCH 2/5] Show time estimates per feature in tooltip
---
cura/PrintInformation.py | 19 ++++++++++++++++
resources/qml/JobSpecs.qml | 46 +++++++++++++++++++++++++++++++++-----
2 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py
index cd1a194254..c6412e2f6f 100644
--- a/cura/PrintInformation.py
+++ b/cura/PrintInformation.py
@@ -52,6 +52,19 @@ class PrintInformation(QObject):
super().__init__(parent)
self._current_print_time = Duration(None, self)
+ self._print_times_per_feature = {
+ "none": Duration(None, self),
+ "inset_0": Duration(None, self),
+ "inset_x": Duration(None, self),
+ "skin": Duration(None, self),
+ "support": Duration(None, self),
+ "skirt": Duration(None, self),
+ "infill": Duration(None, self),
+ "support_infill": Duration(None, self),
+ "travel": Duration(None, self),
+ "retract": Duration(None, self),
+ "support_interface": Duration(None, self)
+ }
self._material_lengths = []
self._material_weights = []
@@ -93,6 +106,10 @@ class PrintInformation(QObject):
def currentPrintTime(self):
return self._current_print_time
+ @pyqtProperty("QVariantMap", notify = currentPrintTimeChanged)
+ def printTimesPerFeature(self):
+ return self._print_times_per_feature
+
materialLengthsChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialLengthsChanged)
@@ -115,9 +132,11 @@ class PrintInformation(QObject):
total_time = 0
for feature, time in time_per_feature.items():
if time != time: # Check for NaN. Engine can sometimes give us weird values.
+ self._print_times_per_feature[feature].setDuration(0)
Logger.log("w", "Received NaN for print duration message")
continue
total_time += time
+ self._print_times_per_feature[feature].setDuration(time)
self._current_print_time.setDuration(total_time)
self.currentPrintTimeChanged.emit()
diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml
index 6013117728..c702cb1ac2 100644
--- a/resources/qml/JobSpecs.qml
+++ b/resources/qml/JobSpecs.qml
@@ -24,6 +24,7 @@ Item {
UM.I18nCatalog { id: catalog; name:"cura"}
property variant printDuration: PrintInformation.currentPrintTime
+ property variant printDurationPerFeature: PrintInformation.printTimesPerFeature
property variant printMaterialLengths: PrintInformation.materialLengths
property variant printMaterialWeights: PrintInformation.materialWeights
property variant printMaterialCosts: PrintInformation.materialCosts
@@ -159,7 +160,7 @@ Item {
UM.RecolorImage
{
id: timeIcon
- anchors.right: timeSpec.left
+ anchors.right: timeSpecPerFeatureTooltipArea.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("save_button_specs_icons").width
@@ -169,15 +170,48 @@ Item {
color: UM.Theme.getColor("text_subtext")
source: UM.Theme.getIcon("print_time")
}
- Text
+ UM.TooltipArea
{
- id: timeSpec
+ id: timeSpecPerFeatureTooltipArea
+ text: {
+ var result = "";
+ if(base.printDurationPerFeature["inset_0"] && base.printDurationPerFeature["inset_0"].totalSeconds > 0)
+ result += "Outer Walls: " + base.printDurationPerFeature["inset_0"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["inset_x"] && base.printDurationPerFeature["inset_x"].totalSeconds > 0)
+ result += "
Inner Walls: " + base.printDurationPerFeature["inset_x"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["skin"] && base.printDurationPerFeature["skin"].totalSeconds > 0)
+ result += "
Skin: " + base.printDurationPerFeature["skin"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["infill"] && base.printDurationPerFeature["infill"].totalSeconds > 0)
+ result += "
Infill: " + base.printDurationPerFeature["infill"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["support_infill"] && base.printDurationPerFeature["support_infill"].totalSeconds > 0)
+ result += "
Support: " + base.printDurationPerFeature["support_infill"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["support_interface"] && base.printDurationPerFeature["support_interface"].totalSeconds > 0)
+ result += "
Support Interface: " + base.printDurationPerFeature["support_interface"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["support"] && base.printDurationPerFeature["support"].totalSeconds > 0)
+ result += "
Helper Structures: " + base.printDurationPerFeature["support"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["travel"] && base.printDurationPerFeature["travel"].totalSeconds > 0)
+ result += "
Travel: " + base.printDurationPerFeature["travel"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["retract"] && base.printDurationPerFeature["retract"].totalSeconds > 0)
+ result += "
Retractions: " + base.printDurationPerFeature["retract"].getDisplayString(UM.DurationFormat.Short)
+ if(base.printDurationPerFeature["none"] && base.printDurationPerFeature["none"].totalSeconds > 0)
+ result += "
Other: " + base.printDurationPerFeature["none"].getDisplayString(UM.DurationFormat.Short)
+ return result;
+ }
+ width: childrenRect.width
+ height: childrenRect.height
anchors.right: lengthIcon.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
- font: UM.Theme.getFont("small")
- color: UM.Theme.getColor("text_subtext")
- text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
+
+ Text
+ {
+ id: timeSpec
+ anchors.left: parent.left
+ anchors.top: parent.top
+ font: UM.Theme.getFont("small")
+ color: UM.Theme.getColor("text_subtext")
+ text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
+ }
}
UM.RecolorImage
{
From 05f46c47f72d0a520e74ee779791989a25e25227 Mon Sep 17 00:00:00 2001
From: 14bitVoid <14bitvoid@protonmail.com>
Date: Fri, 5 May 2017 02:31:16 +0200
Subject: [PATCH 3/5] Dynamically fill tooltip with time estimates
---
resources/qml/JobSpecs.qml | 42 ++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml
index c702cb1ac2..849d9f43da 100644
--- a/resources/qml/JobSpecs.qml
+++ b/resources/qml/JobSpecs.qml
@@ -174,27 +174,29 @@ Item {
{
id: timeSpecPerFeatureTooltipArea
text: {
+ var order = ["inset_0", "inset_x", "skin", "infill", "support_infill", "support_interface", "support", "travel", "retract", "none"];
+ var visible_names = {
+ "inset_0": "Outer Wall",
+ "inset_x": "Inner Walls",
+ "skin": "Skin",
+ "infill": "Infill",
+ "support_infill": "Support",
+ "support_interface": "Support Interface",
+ "support": "Helper Structures",
+ "travel": "Travel",
+ "retract": "Retractions",
+ "none": "Other"
+ };
var result = "";
- if(base.printDurationPerFeature["inset_0"] && base.printDurationPerFeature["inset_0"].totalSeconds > 0)
- result += "Outer Walls: " + base.printDurationPerFeature["inset_0"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["inset_x"] && base.printDurationPerFeature["inset_x"].totalSeconds > 0)
- result += "
Inner Walls: " + base.printDurationPerFeature["inset_x"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["skin"] && base.printDurationPerFeature["skin"].totalSeconds > 0)
- result += "
Skin: " + base.printDurationPerFeature["skin"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["infill"] && base.printDurationPerFeature["infill"].totalSeconds > 0)
- result += "
Infill: " + base.printDurationPerFeature["infill"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["support_infill"] && base.printDurationPerFeature["support_infill"].totalSeconds > 0)
- result += "
Support: " + base.printDurationPerFeature["support_infill"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["support_interface"] && base.printDurationPerFeature["support_interface"].totalSeconds > 0)
- result += "
Support Interface: " + base.printDurationPerFeature["support_interface"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["support"] && base.printDurationPerFeature["support"].totalSeconds > 0)
- result += "
Helper Structures: " + base.printDurationPerFeature["support"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["travel"] && base.printDurationPerFeature["travel"].totalSeconds > 0)
- result += "
Travel: " + base.printDurationPerFeature["travel"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["retract"] && base.printDurationPerFeature["retract"].totalSeconds > 0)
- result += "
Retractions: " + base.printDurationPerFeature["retract"].getDisplayString(UM.DurationFormat.Short)
- if(base.printDurationPerFeature["none"] && base.printDurationPerFeature["none"].totalSeconds > 0)
- result += "
Other: " + base.printDurationPerFeature["none"].getDisplayString(UM.DurationFormat.Short)
+ for(var feature in order)
+ {
+ feature = order[feature];
+ if(base.printDurationPerFeature[feature] && base.printDurationPerFeature[feature].totalSeconds > 0)
+ {
+ result += "
" + visible_names[feature] + ": " + base.printDurationPerFeature[feature].getDisplayString(UM.DurationFormat.Short);
+ }
+ }
+ result = result.replace(/^\
/, ""); // remove newline before first item
return result;
}
width: childrenRect.width
From e9d70a8a70290d7c5af0b60a430c39765f68f9c5 Mon Sep 17 00:00:00 2001
From: 14bitVoid <14bitvoid@protonmail.com>
Date: Fri, 5 May 2017 02:36:22 +0200
Subject: [PATCH 4/5] Translate features for time estimates
---
resources/qml/JobSpecs.qml | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml
index 849d9f43da..8e89dc6dbc 100644
--- a/resources/qml/JobSpecs.qml
+++ b/resources/qml/JobSpecs.qml
@@ -176,16 +176,16 @@ Item {
text: {
var order = ["inset_0", "inset_x", "skin", "infill", "support_infill", "support_interface", "support", "travel", "retract", "none"];
var visible_names = {
- "inset_0": "Outer Wall",
- "inset_x": "Inner Walls",
- "skin": "Skin",
- "infill": "Infill",
- "support_infill": "Support",
- "support_interface": "Support Interface",
- "support": "Helper Structures",
- "travel": "Travel",
- "retract": "Retractions",
- "none": "Other"
+ "inset_0": catalog.i18nc("@tooltip", "Outer Wall"),
+ "inset_x": catalog.i18nc("@tooltip", "Inner Walls"),
+ "skin": catalog.i18nc("@tooltip", "Skin"),
+ "infill": catalog.i18nc("@tooltip", "Infill"),
+ "support_infill": catalog.i18nc("@tooltip", "Support"),
+ "support_interface": catalog.i18nc("@tooltip", "Support Interface"),
+ "support": catalog.i18nc("@tooltip", "Helper Structures"),
+ "travel": catalog.i18nc("@tooltip", "Travel"),
+ "retract": catalog.i18nc("@tooltip", "Retractions"),
+ "none": catalog.i18nc("@tooltip", "Other")
};
var result = "";
for(var feature in order)
From 00aff6d2f2809443c3fbb35395dbdaef5d681c33 Mon Sep 17 00:00:00 2001
From: Ghostkeeper
Date: Thu, 11 May 2017 10:29:18 +0200
Subject: [PATCH 5/5] Make feature labels more accurate for support
It's used a bit differently.
Contributes to issue CURA-3773.
---
resources/qml/JobSpecs.qml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml
index 8e89dc6dbc..13d855d993 100644
--- a/resources/qml/JobSpecs.qml
+++ b/resources/qml/JobSpecs.qml
@@ -180,9 +180,9 @@ Item {
"inset_x": catalog.i18nc("@tooltip", "Inner Walls"),
"skin": catalog.i18nc("@tooltip", "Skin"),
"infill": catalog.i18nc("@tooltip", "Infill"),
- "support_infill": catalog.i18nc("@tooltip", "Support"),
+ "support_infill": catalog.i18nc("@tooltip", "Support Infill"),
"support_interface": catalog.i18nc("@tooltip", "Support Interface"),
- "support": catalog.i18nc("@tooltip", "Helper Structures"),
+ "support": catalog.i18nc("@tooltip", "Support"),
"travel": catalog.i18nc("@tooltip", "Travel"),
"retract": catalog.i18nc("@tooltip", "Retractions"),
"none": catalog.i18nc("@tooltip", "Other")