From 726eb97d9ffa199b71d27f94d7f4e8d65818737b Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 13 Jul 2016 11:17:44 +0200 Subject: [PATCH 1/9] Machine_id instead of definition_id is now used to link extruders Contributes to CURA-1898 --- cura/Settings/ExtruderManager.py | 35 +++++++++++----------- cura/Settings/ExtrudersModel.py | 2 +- cura/Settings/MachineManager.py | 2 +- plugins/CuraEngineBackend/StartSliceJob.py | 2 +- plugins/GCodeWriter/GCodeWriter.py | 2 +- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 40798999ec..1d60fe1ff4 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -37,7 +37,7 @@ class ExtruderManager(QObject): if not UM.Application.getInstance().getGlobalContainerStack(): return None #No active machine, so no active extruder. try: - return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)].getId() + return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId() except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None @@ -84,37 +84,35 @@ class ExtruderManager(QObject): ## Adds all extruders of a specific machine definition to the extruder # manager. # - # \param machine_definition The machine to add the extruders for. - def addMachineExtruders(self, machine_definition): + # \param machine_definition The machine definition to add the extruders for. + # \param machine_id The machine_id to add the extruders for. + def addMachineExtruders(self, machine_definition, machine_id): changed = False - machine_id = machine_definition.getId() + machine_definition_id = machine_definition.getId() if machine_id not in self._extruder_trains: self._extruder_trains[machine_id] = { } changed = True - container_registry = UM.Settings.ContainerRegistry.getInstance() if container_registry: - # Add the extruder trains that don't exist yet. - for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition.getId()): + for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition_id): position = extruder_definition.getMetaDataEntry("position", None) if not position: UM.Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId()) if not container_registry.findContainerStacks(machine = machine_id, position = position): # Doesn't exist yet. - self.createExtruderTrain(extruder_definition, machine_definition, position) + self.createExtruderTrain(extruder_definition, machine_definition, position, machine_id) changed = True # Gets the extruder trains that we just created as well as any that still existed. - extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId()) + extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_id) for extruder_train in extruder_trains: self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train # Ensure that the extruder train stacks are linked to global stack. extruder_train.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) changed = True - if changed: - self.extrudersChanged.emit(machine_definition) + self.extrudersChanged.emit(machine_id) ## Creates a container stack for an extruder train. # @@ -127,17 +125,18 @@ class ExtruderManager(QObject): # \param extruder_definition The extruder to create the extruder train for. # \param machine_definition The machine that the extruder train belongs to. # \param position The position of this extruder train in the extruder slots of the machine. - def createExtruderTrain(self, extruder_definition, machine_definition, position): + # \param machine_id The id of the "global" stack this extruder is linked to. + def createExtruderTrain(self, extruder_definition, machine_definition, position, machine_id): # Cache some things. container_registry = UM.Settings.ContainerRegistry.getInstance() - machine_id = machine_definition.getId() + machine_definition_id = machine_definition.getId() # Create a container stack for this extruder. extruder_stack_id = container_registry.uniqueName(extruder_definition.getId()) container_stack = UM.Settings.ContainerStack(extruder_stack_id) container_stack.setName(extruder_definition.getName()) # Take over the display name to display the stack with. container_stack.addMetaDataEntry("type", "extruder_train") - container_stack.addMetaDataEntry("machine", machine_definition.getId()) + container_stack.addMetaDataEntry("machine", machine_id) container_stack.addMetaDataEntry("position", position) container_stack.addContainer(extruder_definition) @@ -145,7 +144,7 @@ class ExtruderManager(QObject): variant = container_registry.findInstanceContainers(id = "empty_variant")[0] if machine_definition.getMetaDataEntry("has_variants"): # First add any variant. Later, overwrite with preference if the preference is valid. - variants = container_registry.findInstanceContainers(definition = machine_id, type = "variant") + variants = container_registry.findInstanceContainers(definition = machine_definition_id, type = "variant") if len(variants) >= 1: variant = variants[0] preferred_variant_id = machine_definition.getMetaDataEntry("preferred_variant") @@ -163,9 +162,9 @@ class ExtruderManager(QObject): if machine_definition.getMetaDataEntry("has_materials"): # First add any material. Later, overwrite with preference if the preference is valid. if machine_definition.getMetaDataEntry("has_variant_materials", default = "False") == "True": - materials = container_registry.findInstanceContainers(type = "material", definition = machine_id, variant = variant.getId()) + materials = container_registry.findInstanceContainers(type = "material", definition = machine_definition_id, variant = variant.getId()) else: - materials = container_registry.findInstanceContainers(type = "material", definition = machine_id) + materials = container_registry.findInstanceContainers(type = "material", definition = machine_definition_id) if len(materials) >= 1: material = materials[0] preferred_material_id = machine_definition.getMetaDataEntry("preferred_material") @@ -247,4 +246,4 @@ class ExtruderManager(QObject): def _addCurrentMachineExtruders(self): global_stack = UM.Application.getInstance().getGlobalContainerStack() if global_stack and global_stack.getBottom(): - self.addMachineExtruders(global_stack.getBottom()) + self.addMachineExtruders(global_stack.getBottom(), global_stack.getId()) diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py index 66462296d3..15e80d3f6b 100644 --- a/cura/Settings/ExtrudersModel.py +++ b/cura/Settings/ExtrudersModel.py @@ -115,7 +115,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel): changed = True manager = ExtruderManager.getInstance() - for extruder in manager.getMachineExtruders(global_container_stack.getBottom().getId()): + for extruder in manager.getMachineExtruders(global_container_stack.getId()): extruder_name = extruder.getName() material = extruder.findContainer({ "type": "material" }) if material: diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1d353729b1..796853ef43 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -292,7 +292,7 @@ class MachineManager(QObject): new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) - ExtruderManager.getInstance().addMachineExtruders(definition) + ExtruderManager.getInstance().addMachineExtruders(definition, new_global_stack.getId()) Application.getInstance().setGlobalContainerStack(new_global_stack) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index cdfcecb6b9..6aa9c4660b 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -129,7 +129,7 @@ class StartSliceJob(Job): self._buildGlobalSettingsMessage(stack) - for extruder_stack in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(stack.getBottom().getId()): + for extruder_stack in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(stack.getId()): self._buildExtruderMessage(extruder_stack) for group in object_groups: diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 25d0a10c62..08105b06e8 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -88,7 +88,7 @@ class GCodeWriter(MeshWriter): data = {"global_quality": serialized} manager = ExtruderManager.getInstance() - for extruder in manager.getMachineExtruders(stack.getBottom().getId()): + for extruder in manager.getMachineExtruders(stack.getId()): extruder_quality = extruder.findContainer({"type": "quality"}) flat_extruder_quality_id = machine_manager.duplicateContainer(extruder_quality.getId()) From b33c2f9c25bcfe2c320923cf5aa71f530ededbc8 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 13 Jul 2016 12:06:07 +0200 Subject: [PATCH 2/9] Even better fallbacks for unknown subprofiles These fallbacks specify their types so that they can be found with the filters. Contributes to issue CURA-844. --- .../VersionUpgrade/VersionUpgrade21to22/MachineInstance.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 197aa9fcb9..664f972615 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -47,11 +47,11 @@ class MachineInstance: raise UM.VersionUpgrade.InvalidVersionException("The version of this machine instance is wrong. It must be 1.") self._type_name = config.get("general", "type") - self._variant_name = config.get("general", "variant", fallback = "empty") + self._variant_name = config.get("general", "variant", fallback = "empty_variant") self._name = config.get("general", "name", fallback = "") self._key = config.get("general", "key", fallback = None) - self._active_profile_name = config.get("general", "active_profile", fallback = "empty") - self._active_material_name = config.get("general", "material", fallback = "empty") + self._active_profile_name = config.get("general", "active_profile", fallback = "empty_quality") + self._active_material_name = config.get("general", "material", fallback = "empty_material") self._machine_setting_overrides = {} for key, value in config["machine_settings"].items(): From dfd56d049f9763867e6c1ad0d18ea44546b60fd3 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 13 Jul 2016 13:08:14 +0200 Subject: [PATCH 3/9] getActiveExtruderStack now returns stack based on machine_id instead of definiton ID Contributes to CURA-1898 --- cura/Settings/ExtruderManager.py | 12 +++++------- cura/Settings/MachineManager.py | 1 - 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 1d60fe1ff4..079b01598e 100644 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -35,10 +35,10 @@ class ExtruderManager(QObject): @pyqtProperty(str, notify = activeExtruderChanged) def activeExtruderStackId(self): if not UM.Application.getInstance().getGlobalContainerStack(): - return None #No active machine, so no active extruder. + return None # No active machine, so no active extruder. try: return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)].getId() - except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. + except KeyError: # Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong. return None ## The instance of the singleton pattern. @@ -74,11 +74,9 @@ class ExtruderManager(QObject): def getActiveExtruderStack(self): global_container_stack = UM.Application.getInstance().getGlobalContainerStack() if global_container_stack: - global_definition_container = UM.Application.getInstance().getGlobalContainerStack().getBottom() - if global_definition_container: - if global_definition_container.getId() in self._extruder_trains: - if str(self._active_extruder_index) in self._extruder_trains[global_definition_container.getId()]: - return self._extruder_trains[global_definition_container.getId()][str(self._active_extruder_index)] + if global_container_stack.getId() in self._extruder_trains: + if str(self._active_extruder_index) in self._extruder_trains[global_container_stack.getId()]: + return self._extruder_trains[global_container_stack.getId()][str(self._active_extruder_index)] return None ## Adds all extruders of a specific machine definition to the extruder diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 796853ef43..23335e3e63 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -239,7 +239,6 @@ class MachineManager(QObject): if self._active_container_stack and self._active_container_stack != self._global_container_stack: self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) self._active_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged) - self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack() if self._active_container_stack: self._active_container_stack.containersChanged.connect(self._onInstanceContainersChanged) From ec0e19e175b8b0f184f07e43ce9dbd04e9f95917 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 13 Jul 2016 14:20:41 +0200 Subject: [PATCH 4/9] Removed material profiles field from sliceinfo --- plugins/SliceInfoPlugin/SliceInfo.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index d3b93aacac..39a55702ab 100644 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -93,7 +93,6 @@ class SliceInfo(Extension): "printtime": print_information.currentPrintTime.getDisplayString(), "filament": material_used, "language": Preferences.getInstance().getValue("general/language"), - "materials_profiles ": {} } for container in global_container_stack.getContainers(): container_id = container.getId() From 3f1bd5b586125040550024b0bda517d14bfb5868 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 13 Jul 2016 14:16:28 +0200 Subject: [PATCH 5/9] Update changelog with corrections done after release Also make sure to include all CureEngine features listed in the online changelog Contributes to CURA-1688 --- plugins/ChangeLogPlugin/ChangeLog.txt | 69 +++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 48e96ce4b6..fea618bd97 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -1,6 +1,11 @@ +[2.1.3] + +*Material Profiles +New material profiles for CPE+, PC, Nylon and TPU for the Ultimaker 2+ family. + [2.1.2] -Cura has been completely reengineered from the ground up for an even more seamless integration between hardware, software and materials. Together with its intuitive new user interface, it’s now also ready for any future developments. For the beginner Cura makes 3D printing incredibly easy, and for more advanced users, there are over 140 new customisable settings. +Cura has been completely reengineered from the ground up for an even more seamless integration between hardware, software and materials. Together with its intuitive new user interface, it’s now also ready for any future developments. For the beginner Cura makes 3D printing incredibly easy, and for more advanced users, there are over 200 customizable settings. *Select Multiple Objects You now have the freedom to select and manipulate multiple objects at the same time. @@ -27,22 +32,66 @@ An optimized 64-bit Windows Cura version is now available. This allows you to lo Cura allows you to set a number of lines/layers instead of millimeters. The engine automatically calculates the right settings. *Per-Object Settings -You can now override individual settings for different objects in advanced mode. +Per-object settings allow you to override individual profile settings per object. -*Fuzzy Skin -Prints the outer walls with a jittering motion to give your object a diffused finish. +*Engine Features -*Wire Printing -The object is printed with a mid-air / net-like structure, following the mesh surface. The build plate will move up and down during diagonal segments. Though not visible in layer view, you can view the result in other software, such as Repetier Host or http://chilipeppr.com/tinyg. +*Line Width +Line width settings added per feature: Global, Walls, Top/Bottom, Infill, Skirt, Support. +<<<<<<< HEAD * Conical Support An experimental filament, cost-reduction feature, for support. +======= +*Pattern Settings +Pattern settings improved per feature: Top/Bottom, Infill, Support. + +*Shell + +*Alternate Skin Rotation +Helps to combat the pillowing problem on top layers. + +*Alternate Extra Wall +For better infill adhesion. + +*Horizontal Expansion +Allows to compensate model x,y-size to get a 1:1 result. + +*Travel + +*Avoid Printed Parts +When moving to the next part to print, avoid collisions between the nozzle and other parts which are already printed. + +*Support + +*Stair Step Height +Sets the balance between sturdy and hard to remove support. By setting steps of the stair-like bottom of the support resting on the model. + +*ZigZag +A new, infill type that’s easily breakable, introduced specially for support. + +*Support Roofs +A new sub-feature to reduce scars the support leaves on overhangs. +>>>>>>> 24c8773... Update changelog with corrections done after release *Support Towers Specialized support for tiny overhang areas. -*ZigZag infill -A new, infill type that’s easily breakable, introduced specially for support. +*Special Modes -* Avoid Printed Parts -While combing, the print head moves around printed parts, avoiding collisions with the nozzle and a part that’s already printed. +*Surface Mode +This mode will print the surface of the mesh instead of the enclosed volume. This used to be called ‘Only follow mesh surface’. In addition to the ‘surface mode’ and ‘normal’, a ‘both’ mode has now been added. This ensures all closed volumes are printed as normal and all loose geometry as single walls. + +*Experimental Features + +*Conical Support +An experimental filament, cost-reduction feature, for support. + +*Draft Shield +Prints a protective wall at a set distance around the object that prevents air from hitting the print, reducing warping. + +*Fuzzy Skin +Prints the outer walls with a jittering motion to give your object a diffuse finish. + +*Wire Printing +The object is printed with a mid-air / net-like structure, following the mesh surface. The build plate will move up and down during diagonal segments. Though not visible in layer view, you can view the result in other software, such as Repetier Host or http://chilipeppr.com/tinyg. From 36c185e92140b02ea030fb8668f776891d8764a8 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 13 Jul 2016 14:31:20 +0200 Subject: [PATCH 6/9] Remove stray git conflict markers --- plugins/ChangeLogPlugin/ChangeLog.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index fea618bd97..c989647fbb 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -39,10 +39,6 @@ Per-object settings allow you to override individual profile settings per object *Line Width Line width settings added per feature: Global, Walls, Top/Bottom, Infill, Skirt, Support. -<<<<<<< HEAD -* Conical Support -An experimental filament, cost-reduction feature, for support. -======= *Pattern Settings Pattern settings improved per feature: Top/Bottom, Infill, Support. From f92f0c52c6f0c10bfafd2f511151cea9c567ff23 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 13 Jul 2016 14:33:42 +0200 Subject: [PATCH 7/9] Another stray conflict marker --- plugins/ChangeLogPlugin/ChangeLog.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index c989647fbb..3d6ffd77c9 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -68,7 +68,6 @@ A new, infill type that’s easily breakable, introduced specially for support. *Support Roofs A new sub-feature to reduce scars the support leaves on overhangs. ->>>>>>> 24c8773... Update changelog with corrections done after release *Support Towers Specialized support for tiny overhang areas. From 66a64a7a2bed09fe29a3787b2163dc00f1e1bdb1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 13 Jul 2016 16:23:49 +0200 Subject: [PATCH 8/9] Removing object from a group is now possible CURA-1891 --- cura/CuraApplication.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 850657c33f..800f2a3b95 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -564,15 +564,17 @@ class CuraApplication(QtApplication): node = Selection.getSelectedObject(0) if node: + group_node = None if node.getParent(): group_node = node.getParent() - if not group_node.callDecoration("isGroup"): - op = RemoveSceneNodeOperation(node) - else: - while group_node.getParent().callDecoration("isGroup"): - group_node = group_node.getParent() - op = RemoveSceneNodeOperation(group_node) + op = RemoveSceneNodeOperation(node) + op.push() + if group_node: + if len(group_node.getChildren()) == 1: + group_node.getChildren()[0].setParent(group_node.getParent()) + op = RemoveSceneNodeOperation(group_node) + op.push() ## Create a number of copies of existing object. @pyqtSlot("quint64", int) From c92b2bc38571aef672369a39c082d20292baebd1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 13 Jul 2016 17:22:54 +0200 Subject: [PATCH 9/9] Changed order of setting properties CURA-1842 --- resources/qml/Settings/SettingItem.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml index 5e37288f4a..69272764c9 100644 --- a/resources/qml/Settings/SettingItem.qml +++ b/resources/qml/Settings/SettingItem.qml @@ -215,8 +215,9 @@ Item { // This ensures that the value in any of the deeper containers need not be removed, which is // needed for the reset button (which deletes the top value) to correctly go back to profile // defaults. - propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) propertyProvider.setPropertyValue("state", "InstanceState.Calculated") + propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry)) + } }