From 6688b99caee09d3ae8e102bd31a8ddcf72d3b0b2 Mon Sep 17 00:00:00 2001 From: Thomas Karl Pietrowski Date: Sat, 3 Sep 2016 14:03:18 +0200 Subject: [PATCH 01/16] 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 02/16] 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 03/16] 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 04/16] 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 570843bbb0806914d829c4c0e19bdbb8cf62bf55 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Sep 2016 11:54:16 +0200 Subject: [PATCH 05/16] Filtering containers now also takes quality_definition into account CURA-1780 --- cura/Settings/ContainerManager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index dcc2b5e863..cb3ae88914 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -586,6 +586,7 @@ class ContainerManager(QObject): new_container = container.duplicate(self._createUniqueId(stack_id, new_name), new_name) self._container_registry.addContainer(new_container) else: + UM.Logger.log("w", "Unable to duplicate profile. It has the wrong type.") return "" return new_name @@ -688,7 +689,9 @@ class ContainerManager(QObject): filter_by_material = False if global_stack.getMetaDataEntry("has_machine_quality"): - criteria["definition"] = global_stack.getBottom().getId() + definition = global_stack.getBottom() + definition_id = definition.getMetaDataEntry("quality_definition", definition.getId()) + criteria["definition"] = definition_id filter_by_material = global_stack.getMetaDataEntry("has_materials") From cb50c612937e8708d13286cc0d6b2652524b0376 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Sep 2016 12:51:37 +0200 Subject: [PATCH 06/16] Added missing import statement CURA-2276 --- cura/PrinterOutputDevice.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 1071cfeebd..dfd1c1d8d6 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -2,6 +2,7 @@ from UM.i18n import i18nCatalog from UM.OutputDevice.OutputDevice import OutputDevice from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject from PyQt5.QtWidgets import QMessageBox +import UM.Settings.ContainerRegistry from enum import IntEnum # For the connection state tracking. from UM.Logger import Logger From bab9e8a28a602751724d78d6285e9b487c9e4d5d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 13 Sep 2016 13:26:58 +0200 Subject: [PATCH 07/16] 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 08/16] 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; } From 4db1db302b27810c664c59cd1fc1e847190accc2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Sep 2016 14:35:45 +0200 Subject: [PATCH 09/16] Changed guid to GUID in the filter We use the veriable as upper. --- cura/PrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index dfd1c1d8d6..300e76a192 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -286,7 +286,7 @@ class PrinterOutputDevice(QObject, OutputDevice): result.append(i18n_catalog.i18nc("@item:material", "No material loaded")) continue - containers = self._container_registry.findInstanceContainers(type = "material", guid = material_id) + containers = self._container_registry.findInstanceContainers(type = "material", GUID = material_id) if containers: result.append(containers[0].getName()) else: From d6e95d27344203b67bc60e6e2c4840a8c4dc48af Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Sep 2016 14:54:17 +0200 Subject: [PATCH 10/16] Added error state for container state if serialization data is none CURA-2359 --- cura/Settings/ContainerManager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index cb3ae88914..e3a0d22299 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -349,6 +349,9 @@ class ContainerManager(QObject): except NotImplementedError: return { "status": "error", "message": "Unable to serialize container"} + if contents is None: + return {"status": "error", "message": "Serialization returned None. Unable to write to file"} + with UM.SaveFile(file_url, "w") as f: f.write(contents) From b707c8d806816182add4762e34d794202bd1fba3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Sep 2016 14:57:00 +0200 Subject: [PATCH 11/16] XML profile now returns serialization data even if it's read only This way exporting read only profiles is possible again. CURA-2359 --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 58e7a89cad..bf3f34b667 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -85,9 +85,6 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer): # base file: global settings + supported machines # machine / variant combination: only changes for itself. def serialize(self): - if self._read_only: - return - registry = UM.Settings.ContainerRegistry.getInstance() base_file = self.getMetaDataEntry("base_file", "") From 89fb92edbddcdea50e9db612a1ca5a0b8fdd09b5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 13 Sep 2016 13:58:02 +0200 Subject: [PATCH 12/16] Disable upgrading current settings altogether The current settings in 2.1 specified a machine instance. In 2.2 they specify a machine definition. There is not enough information in one file to be able to translate that. Contributes to issue CURA-844. --- .../VersionUpgrade/VersionUpgrade21to22/MachineInstance.py | 5 +---- plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index cab1c00852..6510d34cb1 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -91,12 +91,9 @@ class MachineInstance: if has_machine_qualities: #This machine now has machine-quality profiles. active_material += "_" + variant_materials #That means that the profile was split into multiple. - current_settings = "" #The profile didn't know the definition ID when it was upgraded, so it will have been invalid. Sorry, your current settings are lost now. - else: - current_settings = self._name + "_current_settings" containers = [ - current_settings, + "", #The current profile doesn't know the definition ID when it was upgraded, only the instance ID, so it will be invalid. Sorry, your current settings are lost now. active_quality_changes, active_quality, active_material, diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py index 6c940b97cf..ff404c0398 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/Profile.py @@ -80,7 +80,7 @@ class Profile: import VersionUpgrade21to22 # Import here to prevent circular dependencies. if self._name == "Current settings": - self._filename += "_current_settings" #This resolves a duplicate ID arising from how Cura 2.1 stores its current settings. + return None #Can't upgrade these, because the new current profile needs to specify the definition ID and the old file only had the machine instance, not the definition. config = configparser.ConfigParser(interpolation = None) From 31b0f748744b1bc957ab74ea5bdffa18a830935d Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Tue, 13 Sep 2016 15:09:33 +0200 Subject: [PATCH 13/16] Change url of cura stats. CURA-1445 --- plugins/SliceInfoPlugin/SliceInfo.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 359066d1f4..ab9a75d1da 100644 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -46,9 +46,11 @@ class SliceInfoJob(Job): if Platform.isOSX(): kwoptions["context"] = ssl._create_unverified_context() + Logger.log("d", "Sending anonymous slice info to [%s]...", self.url) + try: f = urllib.request.urlopen(self.url, **kwoptions) - Logger.log("i", "Sent anonymous slice info to %s", self.url) + Logger.log("i", "Sent anonymous slice info.") f.close() except urllib.error.HTTPError as http_exception: Logger.log("e", "An HTTP error occurred while trying to send slice information: %s" % http_exception) @@ -59,7 +61,7 @@ class SliceInfoJob(Job): # The data is only sent when the user in question gave permission to do so. All data is anonymous and # no model files are being sent (Just a SHA256 hash of the model). class SliceInfo(Extension): - info_url = "https://stats.youmagine.com/curastats/slice" + info_url = "http://stats.youmagine.com/curastats/slice" def __init__(self): super().__init__() From 9cd6a8c1ae2ad2af5ec56e0dbf6852f3ebf9e005 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 13 Sep 2016 16:44:55 +0200 Subject: [PATCH 14/16] JSON feat: machine_name as a setting for the 3D printer model type (CURA-2360) --- resources/definitions/bq_hephestos.def.json | 1 + resources/definitions/bq_hephestos_2.def.json | 1 + resources/definitions/bq_hephestos_xl.def.json | 1 + resources/definitions/bq_witbox.def.json | 1 + resources/definitions/bq_witbox_2.def.json | 1 + resources/definitions/fdmprinter.def.json | 10 ++++++++++ resources/definitions/grr_neo.def.json | 1 + resources/definitions/innovo_inventor.def.json | 1 + resources/definitions/m180.def.json | 1 + resources/definitions/maker_starter.def.json | 1 + .../definitions/mankati_fullscale_xt_plus.def.json | 1 + resources/definitions/mendel90.def.json | 1 + resources/definitions/printrbot_simple.def.json | 1 + resources/definitions/prusa_i3.def.json | 1 + resources/definitions/prusa_i3_mk2.def.json | 1 + resources/definitions/prusa_i3_xl.def.json | 1 + resources/definitions/rigidbot.def.json | 1 + resources/definitions/rigidbot_big.def.json | 1 + resources/definitions/ultimaker2.def.json | 1 + resources/definitions/ultimaker2_extended.def.json | 1 + .../definitions/ultimaker2_extended_plus.def.json | 1 + resources/definitions/ultimaker2_go.def.json | 1 + resources/definitions/ultimaker2_plus.def.json | 1 + resources/definitions/ultimaker_original.def.json | 1 + resources/definitions/ultimaker_original_dual.def.json | 1 + resources/definitions/ultimaker_original_plus.def.json | 1 + resources/definitions/uniqbot_one.def.json | 1 + 27 files changed, 36 insertions(+) diff --git a/resources/definitions/bq_hephestos.def.json b/resources/definitions/bq_hephestos.def.json index 4c90ae9ecd..b594ed1653 100644 --- a/resources/definitions/bq_hephestos.def.json +++ b/resources/definitions/bq_hephestos.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Prusa i3 Hephestos" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, diff --git a/resources/definitions/bq_hephestos_2.def.json b/resources/definitions/bq_hephestos_2.def.json index e49e7163e8..68f06e390f 100644 --- a/resources/definitions/bq_hephestos_2.def.json +++ b/resources/definitions/bq_hephestos_2.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Hephestos 2" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nM104 S{material_print_temperature} ; Heat up extruder while leveling\nM800 ; Custom GCODE to fire start print procedure\nM109 S{material_print_temperature} ; Makes sure the temperature is correct before printing\n; -- end of START GCODE --" }, "machine_end_gcode": { "default_value": "; -- END GCODE --\nM801 ; Custom GCODE to fire end print procedure\n; -- end of END GCODE --" }, "machine_width": { "default_value": 210 }, diff --git a/resources/definitions/bq_hephestos_xl.def.json b/resources/definitions/bq_hephestos_xl.def.json index 867f5f37aa..7a3b3f27fd 100644 --- a/resources/definitions/bq_hephestos_xl.def.json +++ b/resources/definitions/bq_hephestos_xl.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Prusa i3 Hephestos XL" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, diff --git a/resources/definitions/bq_witbox.def.json b/resources/definitions/bq_witbox.def.json index b8d4cbf015..a0290a4063 100644 --- a/resources/definitions/bq_witbox.def.json +++ b/resources/definitions/bq_witbox.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Witbox" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nG21 ;set units to millimetres\nG90 ;set to absolute positioning\nM106 S0 ;set fan speed to zero (turned off)\nG28 X0 Y0 ;move to the X/Y origin (Home)\nG28 Z0 ;move to the Z origin (Home)\nG1 Z15.0 F1200 ;move Z to position 15.0 mm\nG92 E0 ;zero the extruded length\nG1 E20 F200 ;extrude 20mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F7200 ;set feedrate to 120 mm/s\n; -- end of START GCODE --" }, diff --git a/resources/definitions/bq_witbox_2.def.json b/resources/definitions/bq_witbox_2.def.json index e47d082d0f..ac13c2144c 100644 --- a/resources/definitions/bq_witbox_2.def.json +++ b/resources/definitions/bq_witbox_2.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "BQ Witbox 2" }, "machine_start_gcode": { "default_value": "; -- START GCODE --\nM800 ; Custom GCODE to fire start print procedure\n; -- end of START GCODE --" }, diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index ba823f6d40..10bcb41a38 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -29,6 +29,16 @@ "icon": "category_machine", "children": { + "machine_name": + { + "label": "Machine Type", + "description": "The name of your 3D printer model.", + "default_value": "Unknown", + "type": "str", + "settable_per_mesh": false, + "settable_per_extruder": false, + "settable_per_meshgroup": false + }, "machine_show_variants": { "label": "Show machine variants", diff --git a/resources/definitions/grr_neo.def.json b/resources/definitions/grr_neo.def.json index e4b871303b..e2a4d47b78 100644 --- a/resources/definitions/grr_neo.def.json +++ b/resources/definitions/grr_neo.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "German RepRap Neo" }, "machine_width": { "default_value": 150 }, diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json index dd7e87d446..48c3ace5d9 100644 --- a/resources/definitions/innovo_inventor.def.json +++ b/resources/definitions/innovo_inventor.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "Innovo INVENTOR" }, "machine_width": { "default_value": 340 }, diff --git a/resources/definitions/m180.def.json b/resources/definitions/m180.def.json index bb027d33bc..04859d87b9 100644 --- a/resources/definitions/m180.def.json +++ b/resources/definitions/m180.def.json @@ -12,6 +12,7 @@ }, "overrides": { + "machine_name": { "default_value": "Malyan M180" }, "machine_width": { "default_value": 230 }, diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json index 2718a10f10..4e066ddff2 100644 --- a/resources/definitions/maker_starter.def.json +++ b/resources/definitions/maker_starter.def.json @@ -13,6 +13,7 @@ }, "overrides": { + "machine_name": { "default_value": "3DMaker Starter" }, "machine_width": { "default_value": 210 }, diff --git a/resources/definitions/mankati_fullscale_xt_plus.def.json b/resources/definitions/mankati_fullscale_xt_plus.def.json index 72c8ebdd86..65ed223f9e 100644 --- a/resources/definitions/mankati_fullscale_xt_plus.def.json +++ b/resources/definitions/mankati_fullscale_xt_plus.def.json @@ -12,6 +12,7 @@ "platform": "mankati_fullscale_xt_plus_platform.stl" }, "overrides": { + "machine_name": { "default_value": "Mankati Fullscale XT Plus" }, "machine_width": { "default_value": 260 }, "machine_depth": { "default_value": 260 }, "machine_height": { "default_value": 300 }, diff --git a/resources/definitions/mendel90.def.json b/resources/definitions/mendel90.def.json index 8d9a6d99a1..cce0c3133a 100644 --- a/resources/definitions/mendel90.def.json +++ b/resources/definitions/mendel90.def.json @@ -19,6 +19,7 @@ ], "overrides": { + "machine_name": { "default_value": "Mendel90" }, "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nG92 E0 ;zero the extruded length\nM107 ;start with the fan off\nG1 X90 Y200 F6000 ;go to the middle of the front\nG1 Z0.05 ;close to the bed\nG1 Z0.3 ;lift Z\n" }, diff --git a/resources/definitions/printrbot_simple.def.json b/resources/definitions/printrbot_simple.def.json index 255259df5a..3d082af89d 100644 --- a/resources/definitions/printrbot_simple.def.json +++ b/resources/definitions/printrbot_simple.def.json @@ -13,6 +13,7 @@ }, "overrides": { + "machine_name": { "default_value": "Printrbot Simple" }, "machine_heated_bed": { "default_value": false }, "machine_width": { "default_value": 150 }, "machine_height": { "default_value": 150 }, diff --git a/resources/definitions/prusa_i3.def.json b/resources/definitions/prusa_i3.def.json index 12e7054694..3b1adc5f00 100644 --- a/resources/definitions/prusa_i3.def.json +++ b/resources/definitions/prusa_i3.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "Prusa i3" }, "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/prusa_i3_mk2.def.json b/resources/definitions/prusa_i3_mk2.def.json index 03c14f1107..e0c4475362 100644 --- a/resources/definitions/prusa_i3_mk2.def.json +++ b/resources/definitions/prusa_i3_mk2.def.json @@ -15,6 +15,7 @@ }, "overrides": { + "machine_name": { "default_value": "Prusa i3 Mk2" }, "machine_heated_bed": { "default_value": true }, "machine_width": { "default_value": 250 }, "machine_height": { "default_value": 200 }, diff --git a/resources/definitions/prusa_i3_xl.def.json b/resources/definitions/prusa_i3_xl.def.json index 819a93b860..7dcd6aceaf 100644 --- a/resources/definitions/prusa_i3_xl.def.json +++ b/resources/definitions/prusa_i3_xl.def.json @@ -14,6 +14,7 @@ }, "overrides": { + "machine_name": { "default_value": "Prusa i3 xl" }, "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/rigidbot.def.json b/resources/definitions/rigidbot.def.json index fb8112a582..7266c12a38 100644 --- a/resources/definitions/rigidbot.def.json +++ b/resources/definitions/rigidbot.def.json @@ -13,6 +13,7 @@ }, "overrides": { + "machine_name": { "default_value": "RigidBot" }, "machine_width": { "default_value": 254 }, diff --git a/resources/definitions/rigidbot_big.def.json b/resources/definitions/rigidbot_big.def.json index 7026df646b..9ada143fbc 100644 --- a/resources/definitions/rigidbot_big.def.json +++ b/resources/definitions/rigidbot_big.def.json @@ -13,6 +13,7 @@ }, "overrides": { + "machine_name": { "default_value": "RigidBotBig" }, "machine_width": { "default_value": 400 }, diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json index a0ead36bff..79c89ab068 100644 --- a/resources/definitions/ultimaker2.def.json +++ b/resources/definitions/ultimaker2.def.json @@ -18,6 +18,7 @@ "supported_actions":["UpgradeFirmware"] }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2" }, "machine_start_gcode" : { "default_value": "", "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nG1 X10 Y0 F4000;move X/Y to min endstops\\nG28 Z0 ;move Z to bottom endstops\\nG1 Z15.0 F9000 ;move the platform to 15mm\\nG92 E0 ;zero the extruded length\\nG1 F200 E10 ;extrude 10 mm of feed stock\\nG92 E0 ;zero the extruded length again\\nG1 F9000\\n;Put printing message on LCD screen\\nM117 Printing...\"" diff --git a/resources/definitions/ultimaker2_extended.def.json b/resources/definitions/ultimaker2_extended.def.json index 889046694c..803e9fe896 100644 --- a/resources/definitions/ultimaker2_extended.def.json +++ b/resources/definitions/ultimaker2_extended.def.json @@ -16,6 +16,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2 Extended" }, "machine_height": { "default_value": 305 } diff --git a/resources/definitions/ultimaker2_extended_plus.def.json b/resources/definitions/ultimaker2_extended_plus.def.json index 3454be30f2..4490b67957 100644 --- a/resources/definitions/ultimaker2_extended_plus.def.json +++ b/resources/definitions/ultimaker2_extended_plus.def.json @@ -16,6 +16,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2 Extended+" }, "machine_height": { "default_value": 305 } diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json index 107d413296..5d4c898ade 100644 --- a/resources/definitions/ultimaker2_go.def.json +++ b/resources/definitions/ultimaker2_go.def.json @@ -17,6 +17,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2 Go" }, "machine_width": { "default_value": 120 }, diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json index 9866d65e3d..87c158782c 100644 --- a/resources/definitions/ultimaker2_plus.def.json +++ b/resources/definitions/ultimaker2_plus.def.json @@ -20,6 +20,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker 2+" }, "speed_infill": { "value": "speed_print" }, diff --git a/resources/definitions/ultimaker_original.def.json b/resources/definitions/ultimaker_original.def.json index a4c37e7aa7..03b3b50a08 100644 --- a/resources/definitions/ultimaker_original.def.json +++ b/resources/definitions/ultimaker_original.def.json @@ -18,6 +18,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker Original" }, "machine_width": { "default_value": 205 }, diff --git a/resources/definitions/ultimaker_original_dual.def.json b/resources/definitions/ultimaker_original_dual.def.json index 8d2d5d85d6..48d2436b92 100644 --- a/resources/definitions/ultimaker_original_dual.def.json +++ b/resources/definitions/ultimaker_original_dual.def.json @@ -23,6 +23,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker Original" }, "machine_width": { "default_value": 205 }, diff --git a/resources/definitions/ultimaker_original_plus.def.json b/resources/definitions/ultimaker_original_plus.def.json index 2c83070add..89cc7aa67a 100644 --- a/resources/definitions/ultimaker_original_plus.def.json +++ b/resources/definitions/ultimaker_original_plus.def.json @@ -17,6 +17,7 @@ }, "overrides": { + "machine_name": { "default_value": "Ultimaker Original+" }, "machine_heated_bed": { "default_value": true }, diff --git a/resources/definitions/uniqbot_one.def.json b/resources/definitions/uniqbot_one.def.json index 1342e065a2..a3ab5cc779 100644 --- a/resources/definitions/uniqbot_one.def.json +++ b/resources/definitions/uniqbot_one.def.json @@ -12,6 +12,7 @@ }, "overrides": { + "machine_name": { "default_value": "Uniqbot" }, "machine_heated_bed": { "default_value": false }, From 76e57c940d9b8535ea71696f4ceddaf07f13296f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Sep 2016 17:27:29 +0200 Subject: [PATCH 15/16] Added more specific error message when trying to slice with incompatible material CURA-2271 --- plugins/CuraEngineBackend/CuraEngineBackend.py | 10 ++++++++++ plugins/CuraEngineBackend/StartSliceJob.py | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 72884ce5a5..ec9b050cdd 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -227,6 +227,16 @@ class CuraEngineBackend(Backend): if job.isCancelled() or job.getError() or job.getResult() == StartSliceJob.StartJobResult.Error: return + if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible: + if Application.getInstance().getPlatformActivity: + self._error_message = Message(catalog.i18nc("@info:status", + "The selected material is imcompatible with the selected machine or configuration.")) + self._error_message.show() + self.backendStateChange.emit(BackendState.Error) + else: + self.backendStateChange.emit(BackendState.NotStarted) + return + if job.getResult() == StartSliceJob.StartJobResult.SettingError: if Application.getInstance().getPlatformActivity: self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. Please check your settings for errors.")) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index efc36e6150..d737e684ad 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -24,6 +24,7 @@ class StartJobResult(IntEnum): Error = 2 SettingError = 3 NothingToSlice = 4 + MaterialIncompatible = 5 ## Formatter class that handles token expansion in start/end gcod @@ -86,7 +87,7 @@ class StartSliceJob(Job): material = extruder_stack.findContainer({"type": "material"}) if material: if material.getMetaDataEntry("compatible") == False: - self.setResult(StartJobResult.SettingError) + self.setResult(StartJobResult.MaterialIncompatible) return # Don't slice if there is a per object setting with an error value. From 4d84584f599078b0c3c3aacfb8e2bf532f3f8c7c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 13 Sep 2016 17:31:15 +0200 Subject: [PATCH 16/16] Simplified statement as per review CURA-2271 --- resources/qml/SidebarHeader.qml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index eb465574a2..867bd03b71 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -235,14 +235,15 @@ Column property var valueError: { var data = Cura.ContainerManager.getContainerMetaDataEntry(Cura.MachineManager.activeMaterialId, "compatible") - if(data == "" || data == "True") - { - return false - } if(data == "False") { return true } + else + { + return false + } + } enabled: !extrudersList.visible || base.currentExtruderIndex > -1