From 6688b99caee09d3ae8e102bd31a8ddcf72d3b0b2 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 3 Sep 2016 14:03:18 +0200 Subject: [PATCH 1/6] CURA-1445: Adding md5 hashes ... for every model placed on the build plate. --- plugins/SliceInfoPlugin/SliceInfo.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 047a03575d..d30425d0ac 100644 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -1,6 +1,8 @@ # Copyright (c) 2015 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. +from cura.CuraApplication import CuraApplication + from UM.Extension import Extension from UM.Application import Application from UM.Preferences import Preferences @@ -18,6 +20,7 @@ import math import urllib.request import urllib.parse import ssl +import hashlib catalog = i18nCatalog("cura") @@ -80,6 +83,22 @@ class SliceInfo(Extension): Logger.log("d", "'info/send_slice_info' is turned off.") return # Do nothing, user does not want to send data + # Listing all files placed on the buildplate + filenames = [] + for node in DepthFirstIterator(CuraApplication.getInstance().getController().getScene().getRoot()): + if type(node) is not SceneNode or not node.getMeshData(): + continue + filenames.append(node.getMeshData().getFileName()) + + # Creating md5sums and formatting them as discussed on JIRA + modelhashes = [hashlib.md5(open(filename, 'rb').read()).hexdigest() for filename in filenames] + modelhash_formatted = "" + if modelhashes: + modelhash_formatted = str(modelhashes[0]) + if len(modelhashes) > 1: + for modelhash in modelhashes[1:]: + modelhash_formatted += ",%s" %(modelhash) + global_container_stack = Application.getInstance().getGlobalContainerStack() # Get total material used (in mm^3) @@ -117,7 +136,7 @@ class SliceInfo(Extension): "platform": platform.platform(), "settings": global_container_stack.serialize(), # global_container with references on used containers "version": Application.getInstance().getVersion(), - "modelhash": "None", + "modelhash": modelhash_formatted, "printtime": print_information.currentPrintTime.getDisplayString(DurationFormat.Format.ISO8601), "filament": material_used, "language": Preferences.getInstance().getValue("general/language"), From dd02243790b1952c21ec4c95c7ac84d7625ae593 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Mon, 5 Sep 2016 18:54:52 +0200 Subject: [PATCH 2/6] SliceInfo: Adding log message and pass exception * removes unused "e" * Using logException correctly Conflicts: plugins/SliceInfoPlugin/SliceInfo.py --- plugins/SliceInfoPlugin/SliceInfo.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index d30425d0ac..700d90822a 100644 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -84,14 +84,13 @@ class SliceInfo(Extension): return # Do nothing, user does not want to send data # Listing all files placed on the buildplate - filenames = [] + modelhashes = [] for node in DepthFirstIterator(CuraApplication.getInstance().getController().getScene().getRoot()): if type(node) is not SceneNode or not node.getMeshData(): - continue - filenames.append(node.getMeshData().getFileName()) + continue + modelhashes.append(node.getMeshData().getHash()) # Creating md5sums and formatting them as discussed on JIRA - modelhashes = [hashlib.md5(open(filename, 'rb').read()).hexdigest() for filename in filenames] modelhash_formatted = "" if modelhashes: modelhash_formatted = str(modelhashes[0]) From cf55178a114c6148c9780aed0b8dc64e74a71399 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Mon, 5 Sep 2016 19:05:26 +0200 Subject: [PATCH 3/6] Removing unused code We are collecting here a lot of data, which doesn't get submitted. --- plugins/SliceInfoPlugin/SliceInfo.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 700d90822a..2a2acbacab 100644 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -107,27 +107,6 @@ class SliceInfo(Extension): # TODO: Send material per extruder instead of mashing it on a pile material_used = math.pi * material_radius * material_radius * sum(print_information.materialLengths) #Volume of all materials used - # Get model information (bounding boxes, hashes and transformation matrix) - models_info = [] - for node in DepthFirstIterator(Application.getInstance().getController().getScene().getRoot()): - if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: - if not getattr(node, "_outside_buildarea", False): - model_info = {} - model_info["hash"] = node.getMeshData().getHash() - model_info["bounding_box"] = {} - model_info["bounding_box"]["minimum"] = {} - model_info["bounding_box"]["minimum"]["x"] = node.getBoundingBox().minimum.x - model_info["bounding_box"]["minimum"]["y"] = node.getBoundingBox().minimum.y - model_info["bounding_box"]["minimum"]["z"] = node.getBoundingBox().minimum.z - - model_info["bounding_box"]["maximum"] = {} - model_info["bounding_box"]["maximum"]["x"] = node.getBoundingBox().maximum.x - model_info["bounding_box"]["maximum"]["y"] = node.getBoundingBox().maximum.y - model_info["bounding_box"]["maximum"]["z"] = node.getBoundingBox().maximum.z - model_info["transformation"] = str(node.getWorldTransformation().getData()) - - models_info.append(model_info) - # Bundle the collected data submitted_data = { "processor": platform.processor(), From 8571087f3e9b9e4cb751e6b46367c12135743c0c Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Fri, 9 Sep 2016 00:24:32 +0200 Subject: [PATCH 4/6] CURA-1445: Using .join instead Says in one line what I wanted to do. --- plugins/SliceInfoPlugin/SliceInfo.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 2a2acbacab..eb713f6557 100644 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -91,12 +91,7 @@ class SliceInfo(Extension): modelhashes.append(node.getMeshData().getHash()) # Creating md5sums and formatting them as discussed on JIRA - modelhash_formatted = "" - if modelhashes: - modelhash_formatted = str(modelhashes[0]) - if len(modelhashes) > 1: - for modelhash in modelhashes[1:]: - modelhash_formatted += ",%s" %(modelhash) + modelhash_formatted = ",".join(modelhashes) global_container_stack = Application.getInstance().getGlobalContainerStack() From bab9e8a28a602751724d78d6285e9b487c9e4d5d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 13 Sep 2016 13:26:58 +0200 Subject: [PATCH 5/6] JSON fix: always display support interface extruder (CURA-2308) The interface extruder determines whether an interface should be enabled --- resources/definitions/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 79c4b8734d..ba823f6d40 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2495,7 +2495,7 @@ "description": "Generate a dense interface between the model and the support. This will create a skin at the top of the support on which the model is printed and at the bottom of the support, where it rests on the model.", "type": "bool", "default_value": false, - "global_inherits_stack": "support_extruder_nr", + "global_inherits_stack": "support_interface_extruder_nr", "enabled": "support_enable", "settable_per_mesh": true }, @@ -3283,7 +3283,7 @@ "type": "extruder", "default_value": "0", "value": "support_extruder_nr", - "enabled": "support_enable and machine_extruder_count > 1 and extruderValue(support_interface_extruder_nr, 'support_interface_enable')", + "enabled": "support_enable and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false } From 0fdd9279bbf5962ac595b53d57b8ee020c5aed7d Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Tue, 13 Sep 2016 14:04:49 +0200 Subject: [PATCH 6/6] Resolvement strategy for bed adhesion and prime tower enable. Contributes to CURA-2232 No resolvement strategy for prime_tower_enable and platform adhesion --- resources/definitions/fdmprinter.def.json | 2 ++ resources/qml/Settings/SettingCheckBox.qml | 32 ++++++++++++++++++---- resources/qml/Settings/SettingComboBox.qml | 13 ++++++++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ba823f6d40..e1184ad6ac 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -2705,6 +2705,7 @@ "raft": "Raft" }, "default_value": "brim", + "resolve": "'raft' if 'raft' in extruderValues('adhesion_type') else ('brim' if 'brim' in extruderValues('adhesion_type') else 'skirt')", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -3296,6 +3297,7 @@ "type": "bool", "enabled": "machine_extruder_count > 1", "default_value": false, + "resolve": "max(extruderValues('prime_tower_enable'))", "settable_per_mesh": false, "settable_per_extruder": false }, diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml index 9b50c82395..1fcd24ccf6 100644 --- a/resources/qml/Settings/SettingCheckBox.qml +++ b/resources/qml/Settings/SettingCheckBox.qml @@ -20,18 +20,40 @@ SettingItem property bool checked: { - switch(propertyProvider.properties.value) + // FIXME this needs to go away once 'resolve' is combined with 'value' in our data model. + // Stacklevels + // 0: user -> unsaved change + // 1: quality changes -> saved change + // 2: quality + // 3: material -> user changed material in materials page + // 4: variant + // 5: machine + var value; + if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { + // We have a resolve function. Indicates that the setting is not settable per extruder and that + // we have to choose between the resolved value (default) and the global value + // (if user has explicitly set this). + value = propertyProvider.properties.resolve; + } else { + value = propertyProvider.properties.value; + } + + switch(value) { case "True": - return true + return true; case "False": - return false + return false; default: - return propertyProvider.properties.value + return value; } } - onClicked: { forceActiveFocus(); propertyProvider.setPropertyValue("value", !checked) } + onClicked: + { + forceActiveFocus(); + propertyProvider.setPropertyValue("value", !checked); + } Rectangle { diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml index 283e309e6a..0f6bab438d 100644 --- a/resources/qml/Settings/SettingComboBox.qml +++ b/resources/qml/Settings/SettingComboBox.qml @@ -96,8 +96,19 @@ SettingItem } function updateCurrentIndex() { + // FIXME this needs to go away once 'resolve' is combined with 'value' in our data model. + var value; + if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) { + // We have a resolve function. Indicates that the setting is not settable per extruder and that + // we have to choose between the resolved value (default) and the global value + // (if user has explicitly set this). + value = propertyProvider.properties.resolve; + } else { + value = propertyProvider.properties.value; + } + for(var i = 0; i < definition.options.length; ++i) { - if(definition.options[i].key == propertyProvider.properties.value) { + if(definition.options[i].key == value) { currentIndex = i; return; }