From 8f66db6565e891f7e29f4d528d005dc88fc1916b Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Mon, 18 Dec 2017 13:29:10 +0100 Subject: [PATCH 01/36] Remove overzealeous log message This message appears on every machine in every material, which is far too much. --- plugins/XmlMaterialProfile/XmlMaterialProfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index c31a60c778..125fe1e344 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -737,7 +737,6 @@ class XmlMaterialProfile(InstanceContainer): Logger.log("w", "No definition found for machine ID %s", machine_id) continue - Logger.log("d", "Found def for machine [%s]", machine_id) definition_metadata = definition_metadata[0] machine_manufacturer = identifier.get("manufacturer", definition_metadata.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition. From d6c6aa1c7197775d51292d3c746369875b41e983 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Mon, 18 Dec 2017 17:03:18 +0100 Subject: [PATCH 02/36] CURA-4715 fix updating custom profile --- cura/Settings/ContainerManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index bbabdadbde..209e1ec8fd 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -514,7 +514,7 @@ class ContainerManager(QObject): for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks(): # Find the quality_changes container for this stack and merge the contents of the top container into it. quality_changes = stack.qualityChanges - if not quality_changes or quality_changes.isReadOnly(): + if not quality_changes or self._container_registry.isReadOnly(quality_changes.getId()): Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId()) continue @@ -687,7 +687,7 @@ class ContainerManager(QObject): global_stack = Application.getInstance().getGlobalContainerStack() if not global_stack or not quality_name: return "" - machine_definition = global_stack.getBottom() + machine_definition = global_stack.definition active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() if active_stacks is None: From cab27711ad94a3ce0e8b9a3239d24757349c49d5 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 18 Dec 2017 20:50:45 +0100 Subject: [PATCH 03/36] Cleanup readme Cleanup readme now that we have better Wiki content --- README.md | 55 +++++++++++++------------------------------------------ 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 90f17a5463..a94ca853e6 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,16 @@ Cura ==== - -This is the new, shiny frontend for Cura. [daid/Cura](https://github.com/daid/Cura.git) is the old legacy Cura that everyone knows and loves/hates. - -We re-worked the whole GUI code at Ultimaker, because the old code started to become unmaintainable. - +This is the new, shiny frontend for Cura. [daid/Cura](https://github.com/daid/Cura.git) is the old legacy Cura that everyone knows and loves/hates. We re-worked the whole GUI code at Ultimaker, because the old code started to become unmaintainable. Logging Issues ------------ -Use [this](https://github.com/Ultimaker/Uranium/wiki/Bug-Reporting-Template) template to report issues. New issues that do not adhere to this template will take us a lot longer to handle and will therefore have a lower pirority. - For crashes and similar issues, please attach the following information: * (On Windows) The log as produced by dxdiag (start -> run -> dxdiag -> save output) * The Cura GUI log file, located at - * %APPDATA%\cura\\``\cura.log (Windows), or usually C:\Users\\``\AppData\Roaming\cura\\``\cura.log - * $User/Library/Application Support/cura/``/cura.log (OSX) - * $USER/.local/share/cura/``/cura.log (Ubuntu/Linux) + * `%APPDATA%\cura\\cura.log` (Windows), or usually `C:\Users\\\AppData\Roaming\cura\\cura.log` + * `$USER/Library/Application Support/cura//cura.log` (OSX) + * `$USER/.local/share/cura//cura.log` (Ubuntu/Linux) If the Cura user interface still starts, you can also reach this directory from the application menu in Help -> Show settings folder @@ -24,15 +18,10 @@ For additional support, you could also ask in the #cura channel on FreeNode IRC. Dependencies ------------ - -* [Uranium](https://github.com/Ultimaker/Uranium) - Cura is built on top of the Uranium framework. -* [CuraEngine](https://github.com/Ultimaker/CuraEngine) - This will be needed at runtime to perform the actual slicing. -* [PySerial](https://github.com/pyserial/pyserial) - Only required for USB printing support. -* [python-zeroconf](https://github.com/jstasiak/python-zeroconf) - Only required to detect mDNS-enabled printers +* [Uranium](https://github.com/Ultimaker/Uranium) Cura is built on top of the Uranium framework. +* [CuraEngine](https://github.com/Ultimaker/CuraEngine) This will be needed at runtime to perform the actual slicing. +* [PySerial](https://github.com/pyserial/pyserial) Only required for USB printing support. +* [python-zeroconf](https://github.com/jstasiak/python-zeroconf) Only required to detect mDNS-enabled printers Configuring Cura ---------------- @@ -44,33 +33,15 @@ location = /[path_to_the..]/CuraEngine/build/CuraEngine Build scripts ------------- - Please checkout [cura-build](https://github.com/Ultimaker/cura-build) -Third party plugins +Plugins ------------- -* [Post Processing Plugin](https://github.com/nallath/PostProcessingPlugin): Allows for post-processing scripts to run on g-code. -* [Barbarian Plugin](https://github.com/nallath/BarbarianPlugin): Simple scale tool for imperial to metric. -* [X3G Writer](https://github.com/Ghostkeeper/X3GWriter): Adds support for exporting X3G files. -* [Auto orientation](https://github.com/nallath/CuraOrientationPlugin): Calculate the optimal orientation for a model. -* [OctoPrint Plugin](https://github.com/fieldofview/OctoPrintPlugin): Send printjobs directly to OctoPrint and monitor their progress in Cura. -* [Electric Print Cost Calculator Plugin](https://github.com/zoff99/ElectricPrintCostCalculator): Calculate the electric costs of a print. +Please check our [Wiki](https://github.com/Ultimaker/Cura/wiki/Plugin-Directory) for details about creating and using plugins. -Making profiles for other printers ----------------------------------- -If your make of printer is not in the list of supported printers, and using the "Custom FDM Printer" does not offer enough flexibility, you can use [this](https://github.com/Ultimaker/Cura/blob/master/resources/definitions/ultimaker_original.def.json) as a template. - -* Change the machine ID to something unique -* Change the machine_name to your printer's name -* If you have a 3D model of your platform you can put it in resources/meshes and put its name under platform -* Set your machine's dimensions with machine_width, machine_depth, and machine_height -* If your printer's origin is in the center of the bed, set machine_center_is_zero to true. -* Set your print head dimensions with the machine_head_shape parameters -* Set the start and end gcode in machine_start_gcode and machine_end_gcode - -Once you are done, put the profile you have made into resources/definitions, or in definitions in your cura profile folder. - -If you want to make a definition for a multi-extrusion printer, have a look at [this](https://github.com/Ultimaker/Cura/blob/master/resources/definitions/ultimaker_original_dual.def.json) as a template, along with the two extruder definitions it references [here](https://github.com/Ultimaker/Cura/blob/master/resources/extruders/ultimaker_original_dual_1st.def.json) and [here](https://github.com/Ultimaker/Cura/blob/master/resources/extruders/ultimaker_original_dual_2nd.def.json) +Supported printers +------------- +Please check our [Wiki](https://github.com/Ultimaker/Cura/wiki/Adding-new-machine-profiles-to-Cura/_edit) for guidelines about adding support for new machines. Translating Cura ---------------- From 16ce1e870e782e974c94255967131895d0c64a9c Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 18 Dec 2017 20:57:43 +0100 Subject: [PATCH 04/36] Create GitHub issue template Might help streamlining issue creation and handling. --- .github/ISSUE_TEMPLATE.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..7bdf35455c --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,32 @@ + + +Application Version: + + +Platform: + + +Qt: + + +PyQt: + + +Display Driver: + + +Steps to Reproduce: + + +Actual Results: + + +Expected results: + + +Additional Information: + From 06512e53acf1d2d2c587098fa0c315bc1d459987 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 18 Dec 2017 21:16:11 +0100 Subject: [PATCH 05/36] Move configuration options info to a wiki page As all other info was there already. --- README.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a94ca853e6..e620e6dd6f 100644 --- a/README.md +++ b/README.md @@ -23,25 +23,21 @@ Dependencies * [PySerial](https://github.com/pyserial/pyserial) Only required for USB printing support. * [python-zeroconf](https://github.com/jstasiak/python-zeroconf) Only required to detect mDNS-enabled printers -Configuring Cura ----------------- -Link your CuraEngine backend by inserting the following lines in `$HOME/.config/cura/config.cfg` : -``` -[backend] -location = /[path_to_the..]/CuraEngine/build/CuraEngine -``` - Build scripts ------------- -Please checkout [cura-build](https://github.com/Ultimaker/cura-build) +Please checkout [cura-build](https://github.com/Ultimaker/cura-build) for detailed building instructions. Plugins ------------- -Please check our [Wiki](https://github.com/Ultimaker/Cura/wiki/Plugin-Directory) for details about creating and using plugins. +Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Plugin-Directory) for details about creating and using plugins. Supported printers ------------- -Please check our [Wiki](https://github.com/Ultimaker/Cura/wiki/Adding-new-machine-profiles-to-Cura/_edit) for guidelines about adding support for new machines. +Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Adding-new-machine-profiles-to-Cura/_edit) for guidelines about adding support for new machines. + +Configuring Cura +---------------- +Please check out [Wiki page](https://github.com/Ultimaker/Cura/wiki/Cura-Settings) about configuration options for developers. Translating Cura ---------------- From 80880a871f956e00076c20aac6f52d5fdf1b2803 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 18 Dec 2017 21:17:37 +0100 Subject: [PATCH 06/36] Fixed legacy cura repo link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e620e6dd6f..80f4968cdd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ Cura ==== -This is the new, shiny frontend for Cura. [daid/Cura](https://github.com/daid/Cura.git) is the old legacy Cura that everyone knows and loves/hates. We re-worked the whole GUI code at Ultimaker, because the old code started to become unmaintainable. +This is the new, shiny frontend for Cura. Check [daid/LegacyCura](https://github.com/daid/LegacyCura) for the legacy Cura that everyone knows and loves/hates. We re-worked the whole GUI code at Ultimaker, because the old code started to become unmaintainable. Logging Issues ------------ From c58b11611152ba2ffa4622c8635379652c689ef9 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 18 Dec 2017 21:22:42 +0100 Subject: [PATCH 07/36] Added a license reference to the readme As is custom on most GitHub repositories. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 80f4968cdd..363ff52876 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,7 @@ To submit your translation, ideally you would make two pull requests where all ` After the translation is submitted, the Cura maintainers will check for its completeness and check whether it is consistent. We will take special care to look for common mistakes, such as translating mark-up `` code and such. We are often not fluent in every language, so we expect the translator and the international users to make corrections where necessary. Of course, there will always be some mistakes in every translation. When the next Cura release comes around, some of the texts will have changed and some new texts will have been added. Around the time when the beta is released we will invoke a string freeze, meaning that no developer is allowed to make changes to the texts. Then we will update the translation template `.pot` files and ask all our translators to update their translations. If you are unable to update the translation in time for the actual release, we will remove the language from the drop-down menu in the Preferences window. The translation stays in Cura however, so that someone might pick it up again later and update it with the newest texts. Also, users who had previously selected the language can still continue Cura in their language but English text will appear among the original text. + +License +---------------- +Cura is released under the terms of the LGPLv3 or higher. A copy of this license should be included with the software. From 47822148937705af14cccac049f1791119ccb11e Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Mon, 18 Dec 2017 23:18:22 +0100 Subject: [PATCH 08/36] Fix adding printer support wiki link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 363ff52876..6ea839a300 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Plugin-Direc Supported printers ------------- -Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Adding-new-machine-profiles-to-Cura/_edit) for guidelines about adding support for new machines. +Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Adding-new-machine-profiles-to-Cura) for guidelines about adding support for new machines. Configuring Cura ---------------- From 7a3d05ae8a96976d8acc94d81a56e3c1cf966b21 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 19 Dec 2017 09:20:53 +0100 Subject: [PATCH 09/36] Ignore new plugins --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8d9ba4b2d2..88c4d5b6eb 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,7 @@ plugins/CuraVariSlicePlugin plugins/CuraLiveScriptingPlugin plugins/CuraPrintProfileCreator plugins/OctoPrintPlugin +plugins/CuraCloudPlugin #Build stuff CMakeCache.txt From b3758be12e7567ccaffcd56d3e607124cf6d46d4 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Tue, 19 Dec 2017 11:55:08 +0100 Subject: [PATCH 10/36] Fix selecting cura connect printer preference --- plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py index 853ef72f72..7143b462e6 100644 --- a/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py +++ b/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py @@ -234,7 +234,7 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte def spawnPrintView(self): if self._print_view is None: path = os.path.join(self._plugin_path, "PrintWindow.qml") - self._print_view = Application.getInstance().createQmlComponent(path, {"OutputDevice", self}) + self._print_view = Application.getInstance().createQmlComponent(path, {"OutputDevice": self}) if self._print_view is not None: self._print_view.show() From fd6d3e76a3754dae14f83a45d20685b4ddae6062 Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 19 Dec 2017 13:17:53 +0100 Subject: [PATCH 11/36] Simplified upgrade funtion, typos, check extruder count CURA-4708 --- .../VersionUpgrade30to31.py | 123 +++++++++--------- 1 file changed, 59 insertions(+), 64 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py index c01ff158b1..c350dadefe 100644 --- a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py +++ b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py @@ -129,12 +129,17 @@ class VersionUpgrade30to31(VersionUpgrade): if parser.has_option("values", "machine_nozzle_size"): machine_nozzle_size = parser["values"]["machine_nozzle_size"] - definition_name = parser["general"]["name"] - machine_extruders = self._getSingleExtrusionMachineExtruders(definition_name) + machine_extruder_count = '1' # by default it is 1 and the value cannot be stored in the global stack + if parser.has_option("values", "machine_extruder_count"): + machine_extruder_count = parser["values"]["machine_extruder_count"] - #For single extuder machine we nee only first extruder - if len(machine_extruders) !=0: - if self._updateSingleExtuderDefinitionFile(machine_extruders, machine_nozzle_size): + if machine_extruder_count == '1': + definition_name = parser["general"]["name"] + machine_extruders = self._getSingleExtrusionMachineExtruders(definition_name) + + # For single extruder machine we need only first extruder + if len(machine_extruders) !=0: + self._updateSingleExtruderDefinitionFile(machine_extruders, machine_nozzle_size) parser.remove_option("values", "machine_nozzle_size") # Update version numbers @@ -219,9 +224,9 @@ class VersionUpgrade30to31(VersionUpgrade): machine_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.MachineStack) - machine_instances = [] + machine_instance_id = None - #Find all machine instances + # Find machine instances for item in os.listdir(machine_instances_dir): file_path = os.path.join(machine_instances_dir, item) if not os.path.isfile(file_path): @@ -242,57 +247,51 @@ class VersionUpgrade30to31(VersionUpgrade): if not parser.has_option("general", "id"): continue - machine_instances.append(parser) - - #Find for extruders - extruders_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack) - #"machine",[extruders] - extruder_instances_per_machine = {} - - #Find all custom extruders for founded machines - for item in os.listdir(extruders_instances_dir): - file_path = os.path.join(extruders_instances_dir, item) - if not os.path.isfile(file_path): + id = parser["general"]["id"] + if id + "_settings" != definition_name: continue - - parser = configparser.ConfigParser(interpolation=None) - try: - parser.read([file_path]) - except: - # skip, it is not a valid stack file - continue - - if not parser.has_option("metadata", "type"): - continue - if "extruder_train" != parser["metadata"]["type"]: - continue - - if not parser.has_option("metadata", "machine"): - continue - if not parser.has_option("metadata", "position"): - continue - - - for machine_instace in machine_instances: - - machine_id = machine_instace["general"]["id"] - if machine_id != parser["metadata"]["machine"]: - continue - - if machine_id + "_settings" != definition_name: - continue - - if extruder_instances_per_machine.get(machine_id) is None: - extruder_instances_per_machine.update({machine_id:[]}) - - extruder_instances_per_machine.get(machine_id).append(parser) - #the extruder can be related only to one machine + else: + machine_instance_id = id break - return extruder_instances_per_machine + if machine_instance_id is not None: - #Find extruder defition at index 0 and update its values - def _updateSingleExtuderDefinitionFile(self, extruder_instances_per_machine, machine_nozzle_size): + extruders_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack) + #"machine",[extruders] + extruder_instances = [] + + # Find all custom extruders for found machines + for item in os.listdir(extruders_instances_dir): + file_path = os.path.join(extruders_instances_dir, item) + if not os.path.isfile(file_path): + continue + + parser = configparser.ConfigParser(interpolation=None) + try: + parser.read([file_path]) + except: + # skip, it is not a valid stack file + continue + + if not parser.has_option("metadata", "type"): + continue + if "extruder_train" != parser["metadata"]["type"]: + continue + + if not parser.has_option("metadata", "machine"): + continue + if not parser.has_option("metadata", "position"): + continue + + if machine_instance_id != parser["metadata"]["machine"]: + continue + + extruder_instances.append(parser) + + return extruder_instances + + # Find extruder definition at index 0 and update its values + def _updateSingleExtruderDefinitionFile(self, extruder_instances_per_machine, machine_nozzle_size): defintion_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.DefinitionChangesContainer) @@ -312,19 +311,15 @@ class VersionUpgrade30to31(VersionUpgrade): continue name = parser["general"]["name"] custom_extruder_at_0_position = None - for machine_extruders in extruder_instances_per_machine: - for extruder_instance in extruder_instances_per_machine[machine_extruders]: + for extruder_instance in extruder_instances_per_machine: - if extruder_instance["general"]["id"] + "_settings" == name: - defition_position = extruder_instance["metadata"]["position"] + definition_position = extruder_instance["metadata"]["position"] - if defition_position == "0": - custom_extruder_at_0_position = extruder_instance - break - if custom_extruder_at_0_position is not None: + if definition_position == "0": + custom_extruder_at_0_position = extruder_instance break - #If not null, then parsed file is for first extuder and then can be updated. I need to update only + # If not null, then parsed file is for first extuder and then can be updated. I need to update only # first, because this update for single extuder machine if custom_extruder_at_0_position is not None: @@ -374,4 +369,4 @@ class VersionUpgrade30to31(VersionUpgrade): quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer) with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w") as f: - f.write(extruder_quality_changes_output.getvalue()) + f.write(extruder_quality_changes_output.getvalue()) \ No newline at end of file From c5e33e45a427bb25ddb10c632c788d3d8d05d4b7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 13:24:20 +0100 Subject: [PATCH 12/36] Fix setting definition if importing profile without printer-specific profiles Fixes a crash. --- cura/Settings/CuraContainerRegistry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 43e2e072b0..9a19d35c60 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -305,7 +305,7 @@ class CuraContainerRegistry(ContainerRegistry): quality_type_criteria["definition"] = profile.getDefinition().getId() else: - profile.setDefinition(fdmprinter) + profile.setDefinition("fdmprinter") quality_type_criteria["definition"] = "fdmprinter" machine_definition = Application.getInstance().getGlobalContainerStack().getBottom() From 569715492c67c6659e3950b2399f84398beb5429 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 16:05:42 +0100 Subject: [PATCH 13/36] Correct ID if importing multiple legacy profiles They have to be made unique. Contributes to issue CURA-4715. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 32cfb5d027..a0d1442ad8 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2017 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import configparser # For reading the legacy profile INI files. @@ -10,6 +10,7 @@ import os.path # For concatenating the path to the plugin and the relative path from UM.Application import Application # To get the machine manager to create the new profile in. from UM.Logger import Logger # Logging errors. from UM.PluginRegistry import PluginRegistry # For getting the path to this plugin's directory. +from UM.Settings.ContainerRegistry import ContainerRegistry #To create unique profile IDs. from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make. from cura.ProfileReader import ProfileReader # The plug-in type to implement. @@ -77,7 +78,9 @@ class LegacyProfileReader(ProfileReader): raise Exception("Unable to import legacy profile. Multi extrusion is not supported") Logger.log("i", "Importing legacy profile from file " + file_name + ".") - profile = InstanceContainer("Imported Legacy Profile") # Create an empty profile. + container_registry = ContainerRegistry.getInstance() + profile_id = container_registry.uniqueName("Imported Legacy Profile") + profile = InstanceContainer(profile_id) # Create an empty profile. parser = configparser.ConfigParser(interpolation = None) try: @@ -120,7 +123,7 @@ class LegacyProfileReader(ProfileReader): if "translation" not in dict_of_doom: Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?") return None - current_printer_definition = global_container_stack.getBottom() + current_printer_definition = global_container_stack.definition profile.setDefinition(current_printer_definition.getId()) for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations. old_setting_expression = dict_of_doom["translation"][new_setting] @@ -139,12 +142,12 @@ class LegacyProfileReader(ProfileReader): if len(profile.getAllKeys()) == 0: Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") - # We need to downgrade the container to version 1 (in Cura 2.1) so the upgrade system can correctly upgrade # it to the latest version. profile.addMetaDataEntry("type", "profile") # don't know what quality_type it is based on, so use "normal" by default profile.addMetaDataEntry("quality_type", "normal") + profile.setName("Imported Legacy Profile") profile.setDirty(True) parser = configparser.ConfigParser(interpolation=None) From 039c85677a0c8eec71236eaddd52c60b7ef4c94a Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 16:40:03 +0100 Subject: [PATCH 14/36] Also return a global profile Since we always have an extruder now, also for single-extrusion printers, we need to return both a global profile and an extruder profile. Contributes to issue CURA-4713. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index a0d1442ad8..62ac12dc18 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -162,4 +162,8 @@ class LegacyProfileReader(ProfileReader): data = stream.getvalue() profile.deserialize(data) - return profile + global_container_id = container_registry.uniqueName("Global Imported Legacy Profile") + global_profile = profile.duplicate(new_id = global_container_id, new_name = "Imported Legacy Profile") #Needs to have the same name as the extruder profile. + global_profile.setDirty(True) + + return [global_profile, profile] From c6a2b1b9c9053b30f4820300ad027ec87e616300 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 17:08:51 +0100 Subject: [PATCH 15/36] Ignore any additional stacks in imported profile When you import a multi-extrusion file into a single-extrusion printer, don't crash but simply ignore the additional stacks. Contributes to issue CURA-4715. --- cura/Settings/CuraContainerRegistry.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 9a19d35c60..f510a9fca9 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -252,6 +252,9 @@ class CuraContainerRegistry(ContainerRegistry): profile.setMetaDataEntry("extruder", extruder_id) profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_") + else: #More extruders in the imported file than in the machine. + continue #Delete the additional profiles. + result = self._configureProfile(profile, profile_id, new_name) if result is not None: return {"status": "error", "message": catalog.i18nc( From 05e232b498514f20a11fbbfc0f8ca2fe932d44d9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 17:16:32 +0100 Subject: [PATCH 16/36] Move LegacyProfileReader-specific logic into the plug-in itself This had the documentation that it should edit the profiles returned by LegacyProfileReader. Instead, just return correct profiles from the reader... Contributes to issue CURA-4715. --- cura/Settings/CuraContainerRegistry.py | 19 ------------------- .../LegacyProfileReader.py | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index f510a9fca9..26d3484a9f 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -218,25 +218,6 @@ class CuraContainerRegistry(ContainerRegistry): if type(profile_or_list) is not list: profile_or_list = [profile_or_list] - if len(profile_or_list) == 1: - # If there is only 1 stack file it means we're loading a legacy (pre-3.1) .curaprofile. - # In that case we find the per-extruder settings and put those in a new quality_changes container - # so that it is compatible with the new stack setup. - profile = profile_or_list[0] - extruder_stack_quality_changes_container = ContainerManager.getInstance().duplicateContainerInstance(profile) - extruder_stack_quality_changes_container.addMetaDataEntry("extruder", "fdmextruder") - - for quality_changes_setting_key in extruder_stack_quality_changes_container.getAllKeys(): - settable_per_extruder = extruder_stack_quality_changes_container.getProperty(quality_changes_setting_key, "settable_per_extruder") - if settable_per_extruder: - profile.removeInstance(quality_changes_setting_key, postpone_emit = True) - else: - extruder_stack_quality_changes_container.removeInstance(quality_changes_setting_key, postpone_emit = True) - - # We add the new container to the profile list so things like extruder positions are taken care of - # in the next code segment. - profile_or_list.append(extruder_stack_quality_changes_container) - # Import all profiles for profile_index, profile in enumerate(profile_or_list): if profile_index == 0: diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 62ac12dc18..5f80379e49 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -13,6 +13,7 @@ from UM.PluginRegistry import PluginRegistry # For getting the path to this plu from UM.Settings.ContainerRegistry import ContainerRegistry #To create unique profile IDs. from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make. from cura.ProfileReader import ProfileReader # The plug-in type to implement. +from cura.Settings.ExtruderManager import ExtruderManager #To get the current extruder definition. ## A plugin that reads profile data from legacy Cura versions. @@ -142,14 +143,13 @@ class LegacyProfileReader(ProfileReader): if len(profile.getAllKeys()) == 0: Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.") - # We need to downgrade the container to version 1 (in Cura 2.1) so the upgrade system can correctly upgrade - # it to the latest version. profile.addMetaDataEntry("type", "profile") # don't know what quality_type it is based on, so use "normal" by default profile.addMetaDataEntry("quality_type", "normal") profile.setName("Imported Legacy Profile") profile.setDirty(True) + #Serialise and deserialise in order to perform the version upgrade. parser = configparser.ConfigParser(interpolation=None) data = profile.serialize() parser.read_string(data) @@ -162,8 +162,20 @@ class LegacyProfileReader(ProfileReader): data = stream.getvalue() profile.deserialize(data) + #We need to return one extruder stack and one global stack. global_container_id = container_registry.uniqueName("Global Imported Legacy Profile") global_profile = profile.duplicate(new_id = global_container_id, new_name = "Imported Legacy Profile") #Needs to have the same name as the extruder profile. global_profile.setDirty(True) + #Only the extruder stack has an extruder metadata entry. + profile.addMetaDataEntry("extruder", ExtruderManager.getInstance().getActiveExtruderStack().definition) + + #Split all settings into per-extruder and global settings. + for setting_key in profile.getAllKeys(): + settable_per_extruder = global_container_stack.getProperty(setting_key, "settable_per_extruder") + if settable_per_extruder: + global_profile.removeInstance(setting_key) + else: + profile.removeInstance(setting_key) + return [global_profile, profile] From fc784021460c04d51026a898a173ea7de108855b Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 19 Dec 2017 17:26:30 +0100 Subject: [PATCH 17/36] CURA-4726 Using a string for the per object stack id instead of the id of the instance (that is an integer) because the new ContainerRegistry searches by string --- cura/Settings/SettingOverrideDecorator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index c70d9343cf..acd161c6a6 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -32,14 +32,14 @@ class SettingOverrideDecorator(SceneNodeDecorator): def __init__(self): super().__init__() - self._stack = PerObjectContainerStack(stack_id = id(self)) + self._stack = PerObjectContainerStack(stack_id = "per_object_stack") self._stack.setDirty(False) # This stack does not need to be saved. self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer")) self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId() self._stack.propertyChanged.connect(self._onSettingChanged) - ContainerRegistry.getInstance().addContainer(self._stack) + Application.getInstance().getContainerRegistry().addContainer(self._stack) Application.getInstance().globalContainerStackChanged.connect(self._updateNextStack) self.activeExtruderChanged.connect(self._updateNextStack) From d9bc561d7398f95939208fe25d1f9d38663b7db4 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 17:28:05 +0100 Subject: [PATCH 18/36] Set the extruder metadata to its ID Not the actual extruder! Contributes to issue CURA-4715. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 5f80379e49..84fbeccb50 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -168,7 +168,7 @@ class LegacyProfileReader(ProfileReader): global_profile.setDirty(True) #Only the extruder stack has an extruder metadata entry. - profile.addMetaDataEntry("extruder", ExtruderManager.getInstance().getActiveExtruderStack().definition) + profile.addMetaDataEntry("extruder", ExtruderManager.getInstance().getActiveExtruderStack().definition.getId()) #Split all settings into per-extruder and global settings. for setting_key in profile.getAllKeys(): From 21d46d73b5e69eb0c3b5143e7a3e57c239c567c0 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 17:30:10 +0100 Subject: [PATCH 19/36] Add new CAD plugins --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 88c4d5b6eb..510fbfe006 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,8 @@ plugins/CuraLiveScriptingPlugin plugins/CuraPrintProfileCreator plugins/OctoPrintPlugin plugins/CuraCloudPlugin +plugins/CuraBlenderPlugin +plugins/CuraOpenSCADPlugin #Build stuff CMakeCache.txt From 85debb2577ba2493fc59324b3e22ece072a4e798 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 17:31:36 +0100 Subject: [PATCH 20/36] Sort list of plugins alphabetically --- .gitignore | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 510fbfe006..71e83433cf 100644 --- a/.gitignore +++ b/.gitignore @@ -33,23 +33,23 @@ cura.desktop .settings #Externally located plug-ins. -plugins/CuraSolidWorksPlugin -plugins/Doodle3D-cura-plugin -plugins/GodMode -plugins/PostProcessingPlugin -plugins/X3GWriter -plugins/FlatProfileExporter -plugins/ProfileFlattener -plugins/cura-god-mode-plugin plugins/cura-big-flame-graph +plugins/cura-god-mode-plugin plugins/cura-siemensnx-plugin -plugins/CuraVariSlicePlugin -plugins/CuraLiveScriptingPlugin -plugins/CuraPrintProfileCreator -plugins/OctoPrintPlugin -plugins/CuraCloudPlugin plugins/CuraBlenderPlugin +plugins/CuraCloudPlugin +plugins/CuraLiveScriptingPlugin plugins/CuraOpenSCADPlugin +plugins/CuraPrintProfileCreator +plugins/CuraSolidWorksPlugin +plugins/CuraVariSlicePlugin +plugins/Doodle3D-cura-plugin +plugins/FlatProfileExporter +plugins/GodMode +plugins/OctoPrintPlugin +plugins/PostProcessingPlugin +plugins/ProfileFlattener +plugins/X3GWriter #Build stuff CMakeCache.txt From 8734460aff01d2a6e7e8f24cf22b88e23442c291 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 19 Dec 2017 17:36:20 +0100 Subject: [PATCH 21/36] Use unique name too if importing multiple legacy profiles Otherwise all of them get the same name and they don't match global/extruder stacks together properly any more. Contributes to issue CURA-4715. --- plugins/LegacyProfileReader/LegacyProfileReader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/LegacyProfileReader/LegacyProfileReader.py b/plugins/LegacyProfileReader/LegacyProfileReader.py index 84fbeccb50..07cd8b0aad 100644 --- a/plugins/LegacyProfileReader/LegacyProfileReader.py +++ b/plugins/LegacyProfileReader/LegacyProfileReader.py @@ -146,7 +146,7 @@ class LegacyProfileReader(ProfileReader): profile.addMetaDataEntry("type", "profile") # don't know what quality_type it is based on, so use "normal" by default profile.addMetaDataEntry("quality_type", "normal") - profile.setName("Imported Legacy Profile") + profile.setName(profile_id) profile.setDirty(True) #Serialise and deserialise in order to perform the version upgrade. @@ -164,7 +164,7 @@ class LegacyProfileReader(ProfileReader): #We need to return one extruder stack and one global stack. global_container_id = container_registry.uniqueName("Global Imported Legacy Profile") - global_profile = profile.duplicate(new_id = global_container_id, new_name = "Imported Legacy Profile") #Needs to have the same name as the extruder profile. + global_profile = profile.duplicate(new_id = global_container_id, new_name = profile_id) #Needs to have the same name as the extruder profile. global_profile.setDirty(True) #Only the extruder stack has an extruder metadata entry. From 8af52fb61b8a3f5efafb827553ae09d682b48485 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 19 Dec 2017 19:44:04 +0100 Subject: [PATCH 22/36] CURA-4726 Creating unique name for the per object stack. Keep the prefix so it is easy to trace when debugging instead of just a number --- cura/Settings/SettingOverrideDecorator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index acd161c6a6..df19f88a26 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -32,7 +32,7 @@ class SettingOverrideDecorator(SceneNodeDecorator): def __init__(self): super().__init__() - self._stack = PerObjectContainerStack(stack_id = "per_object_stack") + self._stack = PerObjectContainerStack(stack_id = "per_object_stack_" + str(id(self))) self._stack.setDirty(False) # This stack does not need to be saved. self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer")) self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId() From 1a6a6f74d5e705dc92e776b9b5feaf4430a645b1 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 12:19:01 +0100 Subject: [PATCH 23/36] Fix SettingOverrideDecorator for non printing meshes CURA-4705 - Do not set a "secret" property in the SceneNode to indicate whether a node is a non-printing-mesh because SceneNode will not copy that property during a deepcopy. Store it in the SettingOverrideDecorator and make it accessible through a decorator call - Try to trigger an auto-slice AFTER the non-printing-meshes flag is updated, not before. --- cura/Settings/SettingOverrideDecorator.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index df19f88a26..135b16116f 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -37,6 +37,8 @@ class SettingOverrideDecorator(SceneNodeDecorator): self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer")) self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId() + self._is_non_printing_mesh = False + self._stack.propertyChanged.connect(self._onSettingChanged) Application.getInstance().getContainerRegistry().addContainer(self._stack) @@ -57,6 +59,8 @@ class SettingOverrideDecorator(SceneNodeDecorator): # Properly set the right extruder on the copy deep_copy.setActiveExtruder(self._extruder_stack) + deep_copy._is_non_printing_mesh = self._is_non_printing_mesh + return deep_copy ## Gets the currently active extruder to print this object with. @@ -80,14 +84,17 @@ class SettingOverrideDecorator(SceneNodeDecorator): container_stack = containers[0] return container_stack.getMetaDataEntry("position", default=None) + def isNonPrintingMesh(self): + return self._is_non_printing_mesh + def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function # Trigger slice/need slicing if the value has changed. if property_name == "value": + self._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings) + Application.getInstance().getBackend().needsSlicing() Application.getInstance().getBackend().tickle() - self._node._non_printing_mesh = any(self._stack.getProperty(setting, "value") for setting in self._non_printing_mesh_settings) - ## Makes sure that the stack upon which the container stack is placed is # kept up to date. def _updateNextStack(self): From b2ac2e0fc79b609b22b6412f635673ecc53be4fc Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 12:22:39 +0100 Subject: [PATCH 24/36] Trust the stack values more than the decorator CURA-4705 A SceneNode and its decorators can be deepcopied. However, the data in some decorators will only be updated when a per-object settings stack triggers a property changed event. That event cannot copied. So, it can happen that a deepcopied SceneNode has inconsistent data in some of its decorators than what's in the per-object settings stack. --- plugins/CuraEngineBackend/StartSliceJob.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index efa0e87b9e..f12b8e656f 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -19,6 +19,10 @@ from UM.Settings.SettingRelation import RelationType from cura.OneAtATimeIterator import OneAtATimeIterator from cura.Settings.ExtruderManager import ExtruderManager + +NON_PRINTING_MESH_SETTINGS = ["anti_overhang_mesh", "infill_mesh", "cutting_mesh"] + + class StartJobResult(IntEnum): Finished = 1 Error = 2 @@ -133,11 +137,13 @@ class StartSliceJob(Job): temp_list = [] has_printing_mesh = False for node in DepthFirstIterator(self._scene.getRoot()): - if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: - _non_printing_mesh = getattr(node, "_non_printing_mesh", False) - if not getattr(node, "_outside_buildarea", False) or _non_printing_mesh: + if node.callDecoration("isSliceable") and type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: + per_object_stack = node.callDecoration("getStack") + is_non_printing_mesh = any(per_object_stack.getProperty(key, "value") for key in NON_PRINTING_MESH_SETTINGS) + + if not getattr(node, "_outside_buildarea", False) or not is_non_printing_mesh: temp_list.append(node) - if not _non_printing_mesh: + if not is_non_printing_mesh: has_printing_mesh = True Job.yieldThread() From 61dd1c98fde94a6b1feb8f001aac8c1e02ab8f7f Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 13:16:29 +0100 Subject: [PATCH 25/36] Fix cases with no per-object settings stack CURA-4705 --- plugins/CuraEngineBackend/StartSliceJob.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index f12b8e656f..4da26aa78f 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -139,7 +139,9 @@ class StartSliceJob(Job): for node in DepthFirstIterator(self._scene.getRoot()): if node.callDecoration("isSliceable") and type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: per_object_stack = node.callDecoration("getStack") - is_non_printing_mesh = any(per_object_stack.getProperty(key, "value") for key in NON_PRINTING_MESH_SETTINGS) + is_non_printing_mesh = False + if per_object_stack: + is_non_printing_mesh = any(per_object_stack.getProperty(key, "value") for key in NON_PRINTING_MESH_SETTINGS) if not getattr(node, "_outside_buildarea", False) or not is_non_printing_mesh: temp_list.append(node) From 4f28dec8845d7666b9e920a6f0e0300dcf553f3b Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 13:19:48 +0100 Subject: [PATCH 26/36] Fix typo --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 16fd2ee93c..26901c3abc 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -583,7 +583,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): if machine_id: new_machine_id = self.getNewId(machine_id) new_id = new_machine_id + "_current_settings" - instance_container.setMetadataEntry("id", new_id) + instance_container.setMetaDataEntry("id", new_id) instance_container.setName(new_id) instance_container.setMetaDataEntry("machine", new_machine_id) containers_to_add.append(instance_container) From 196bffd3ad6fd026a5e9bc5a04ff570160aeff6e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 13:20:22 +0100 Subject: [PATCH 27/36] Only try to get a new unique name when it already exists CURA-4704 --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 26901c3abc..a7dad68519 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -461,7 +461,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader): global_stack_id_new = self.getNewId(global_stack_id_original) global_stack_need_rename = True - global_stack_name_new = self._container_registry.uniqueName(global_stack_name_original) + if self._container_registry.findContainerStacksMetadata(name = global_stack_id_original): + global_stack_name_new = self._container_registry.uniqueName(global_stack_name_original) for each_extruder_stack_file in extruder_stack_files: old_container_id = self._stripFileToId(each_extruder_stack_file) From 588335c6db112e82810bb421832374538221deef Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 13:42:55 +0100 Subject: [PATCH 28/36] Make sure only single-extrusion machines will be fixed CURA-4713 --- cura/Settings/CuraContainerRegistry.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 26d3484a9f..089d513071 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -406,6 +406,10 @@ class CuraContainerRegistry(ContainerRegistry): if not isinstance(container, ContainerStack) or container.getMetaDataEntry("type") != "machine": return + machine_extruder_trains = container.getMetaDataEntry("machine_extruder_trains") + if machine_extruder_trains is not None and machine_extruder_trains != {"0": "fdmextruder"}: + return + extruder_stacks = self.findContainerStacks(type = "extruder_train", machine = container.getId()) if not extruder_stacks: self.addExtruderStackForSingleExtrusionMachine(container, "fdmextruder") From 49ee2a543e9b1f790db9b7ded62a9b0c05323a04 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 13:57:48 +0100 Subject: [PATCH 29/36] Fix code style --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index b36fb989f0..fd1aa2c7b0 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -432,7 +432,7 @@ Cura.MachineAction property int areaHeight: parent.height - y property string settingKey: "machine_extruder_start_code" property bool isExtruderSetting: true - } + } } Column { height: parent.height @@ -714,7 +714,7 @@ Cura.MachineAction width: gcodeArea.width text: _tooltip - property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting + property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false : isExtruderSetting property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip UM.SettingPropertyProvider From 6d06d184076af5174516e61c0a72080c097b28e0 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 13:58:02 +0100 Subject: [PATCH 30/36] Fix Extruder tabs in MachineSettings dialog CURA-4722 The extruder field views should be bound to the actual extruder, not the active extruder. --- plugins/MachineSettingsAction/MachineSettingsAction.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index fd1aa2c7b0..da3de4f4fc 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -726,7 +726,7 @@ Cura.MachineAction { if(settingsTabs.currentIndex > 0) { - return Cura.MachineManager.activeStackId; + return Cura.ExtruderManager.extruderIds[String(settingsTabs.currentIndex - 1)]; } return ""; } From ae86a838e0d228503131d191c621aed06da9dbf6 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 16:23:39 +0100 Subject: [PATCH 31/36] Update extruder count model in MachineSettings dialog CURA-4722 --- .../MachineSettingsAction.qml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml index da3de4f4fc..6ff70a1503 100644 --- a/plugins/MachineSettingsAction/MachineSettingsAction.qml +++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml @@ -270,6 +270,20 @@ Cura.MachineAction } } } + + Connections + { + target: manager + onDefinedExtruderCountChanged: + { + extruderCountModel.clear(); + for(var i = 0; i < manager.definedExtruderCount; ++i) + { + extruderCountModel.append({text: String(i + 1), value: i}); + } + } + } + currentIndex: machineExtruderCountProvider.properties.value - 1 onActivated: { From 107f6aff786157016e622964abb2675b09f2c311 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 20 Dec 2017 16:48:57 +0100 Subject: [PATCH 32/36] Fix SolidView to use isNonPrintingMesh decorator call CURA-4705 --- plugins/SolidView/SolidView.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py index e96c7e9bda..e156e655ce 100644 --- a/plugins/SolidView/SolidView.py +++ b/plugins/SolidView/SolidView.py @@ -110,7 +110,7 @@ class SolidView(View): except ValueError: pass - if getattr(node, "_non_printing_mesh", False): + if node.callDecoration("isNonPrintingMesh"): if per_mesh_stack and (per_mesh_stack.getProperty("infill_mesh", "value") or per_mesh_stack.getProperty("cutting_mesh", "value")): renderer.queueNode(node, shader = self._non_printing_shader, uniforms = uniforms, transparent = True) else: From 419dc6f59a9aa8148b03ccec03be4adf1fe3eb79 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 21 Dec 2017 09:14:31 +0100 Subject: [PATCH 33/36] Improve issue template a bit --- .github/ISSUE_TEMPLATE.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 7bdf35455c..b78b9b91a2 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,32 +1,36 @@ -Application Version: +**Application Version** -Platform: +**Platform** -Qt: +**Qt** -PyQt: +**PyQt** -Display Driver: +**Display Driver** -Steps to Reproduce: +**Steps to Reproduce** -Actual Results: +**Actual Results** -Expected results: +**Expected results** -Additional Information: +**Additional Information** From 0a0db39f0288afe188cfc66e43a0484bb5b057f7 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 21 Dec 2017 09:27:05 +0100 Subject: [PATCH 34/36] deepcopy value from the stack CURA-4705 --- cura/Settings/SettingOverrideDecorator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index 135b16116f..b853c06c8e 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -59,7 +59,9 @@ class SettingOverrideDecorator(SceneNodeDecorator): # Properly set the right extruder on the copy deep_copy.setActiveExtruder(self._extruder_stack) - deep_copy._is_non_printing_mesh = self._is_non_printing_mesh + # use value from the stack because there can be a delay in signal triggering and "_is_non_printing_mesh" + # has not been updated yet. + deep_copy._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings) return deep_copy From eaa27114c63101a86d0546d1ff0b1ec336db9164 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 21 Dec 2017 12:43:50 +0100 Subject: [PATCH 35/36] Fix ID changing in project loading --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index a7dad68519..40d64590f5 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -682,12 +682,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): file_name = global_stack_file) # Ensure a unique ID and name - stack._id = global_stack_id_new - - # Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the - # bound machine also needs to change. - if stack.getMetaDataEntry("machine", None): - stack.setMetaDataEntry("machine", global_stack_id_new) + stack.setMetaDataEntry("id", global_stack_id_new) # Only machines need a new name, stacks may be non-unique stack.setName(global_stack_name_new) @@ -741,7 +736,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): stack.deserialize(extruder_file_content, file_name = extruder_stack_file) # Ensure a unique ID and name - stack._id = new_id + stack.setMetaDataEntry("id", new_id) self._container_registry.addContainer(stack) extruder_stacks_added.append(stack) From 0e1cd9957877180006c86557ed3f9979b18372f4 Mon Sep 17 00:00:00 2001 From: ChrisTerBeke Date: Thu, 21 Dec 2017 17:08:44 +0100 Subject: [PATCH 36/36] Add flag to ignore discard or keep dialog when changing print setup --- cura/Settings/MachineManager.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 05aed1f5e2..b3a2e6612b 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -739,7 +739,7 @@ class MachineManager(QObject): ## Set the active material by switching out a container # Depending on from/to material+current variant, a quality profile is chosen and set. @pyqtSlot(str) - def setActiveMaterial(self, material_id: str): + def setActiveMaterial(self, material_id: str, always_discard_changes = False): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id) if not containers or not self._active_container_stack: @@ -821,10 +821,10 @@ class MachineManager(QObject): if not old_quality_changes: new_quality_id = candidate_quality.getId() - self.setActiveQuality(new_quality_id) + self.setActiveQuality(new_quality_id, always_discard_changes = always_discard_changes) @pyqtSlot(str) - def setActiveVariant(self, variant_id: str): + def setActiveVariant(self, variant_id: str, always_discard_changes = False): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id) if not containers or not self._active_container_stack: @@ -840,14 +840,14 @@ class MachineManager(QObject): if old_material: preferred_material_name = old_material.getName() preferred_material_id = self._updateMaterialContainer(self._global_container_stack.definition, self._global_container_stack, containers[0], preferred_material_name).id - self.setActiveMaterial(preferred_material_id) + self.setActiveMaterial(preferred_material_id, always_discard_changes = always_discard_changes) else: Logger.log("w", "While trying to set the active variant, no variant was found to replace.") ## set the active quality # \param quality_id The quality_id of either a quality or a quality_changes @pyqtSlot(str) - def setActiveQuality(self, quality_id: str): + def setActiveQuality(self, quality_id: str, always_discard_changes = False): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): self.blurSettings.emit() @@ -909,7 +909,7 @@ class MachineManager(QObject): # the dialog will be the those before the switching. self._executeDelayedActiveContainerStackChanges() - if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: + if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1 and not always_discard_changes: Application.getInstance().discardOrKeepProfileChanges() ## Used to update material and variant in the active container stack with a delay.