diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 117ac2a178..359066d1f4 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,16 @@ 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 + modelhashes = [] + for node in DepthFirstIterator(CuraApplication.getInstance().getController().getScene().getRoot()): + if type(node) is not SceneNode or not node.getMeshData(): + continue + modelhashes.append(node.getMeshData().getHash()) + + # Creating md5sums and formatting them as discussed on JIRA + modelhash_formatted = ",".join(modelhashes) + global_container_stack = Application.getInstance().getGlobalContainerStack() # Get total material used (in mm^3) @@ -89,27 +102,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(), @@ -117,7 +109,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"), diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 79c4b8734d..e1184ad6ac 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 }, @@ -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 }, @@ -3283,7 +3284,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 } @@ -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; }