diff --git a/cura/Machines/MachineErrorChecker.py b/cura/Machines/MachineErrorChecker.py index cfeeb630df..4c6ed891b1 100644 --- a/cura/Machines/MachineErrorChecker.py +++ b/cura/Machines/MachineErrorChecker.py @@ -58,7 +58,6 @@ class MachineErrorChecker(QObject): # Whenever the machine settings get changed, we schedule an error check. self._machine_manager.globalContainerChanged.connect(self.startErrorCheck) - self._machine_manager.globalValueChanged.connect(self.startErrorCheck) self._onMachineChanged() diff --git a/cura/Machines/MachineNode.py b/cura/Machines/MachineNode.py index 3a8a319b0b..29968512ce 100644 --- a/cura/Machines/MachineNode.py +++ b/cura/Machines/MachineNode.py @@ -85,9 +85,9 @@ class MachineNode(ContainerNode): continue quality_groups[quality_type] = QualityGroup(name = global_quality_node.getMetaDataEntry("name", "Unnamed profile"), quality_type = quality_type) quality_groups[quality_type].node_for_global = global_quality_node - for extruder, qualities_per_type in enumerate(qualities_per_type_per_extruder): + for extruder_position, qualities_per_type in enumerate(qualities_per_type_per_extruder): if quality_type in qualities_per_type: - quality_groups[quality_type].nodes_for_extruders[extruder] = qualities_per_type[quality_type] + quality_groups[quality_type].setExtruderNode(extruder_position, qualities_per_type[quality_type]) available_quality_types = set(quality_groups.keys()) for extruder_nr, qualities_per_type in enumerate(qualities_per_type_per_extruder): @@ -134,6 +134,9 @@ class MachineNode(ContainerNode): groups_by_name[name] = QualityChangesGroup(name, quality_type = quality_changes["quality_type"], intent_category = quality_changes.get("intent_category", "default"), parent = CuraApplication.getInstance()) + # CURA-6882 + # Custom qualities are always available, even if they are based on the "not supported" profile. + groups_by_name[name].is_available = True elif groups_by_name[name].intent_category == "default": # Intent category should be stored as "default" if everything is default or as the intent if any of the extruder have an actual intent. groups_by_name[name].intent_category = quality_changes.get("intent_category", "default") @@ -142,14 +145,6 @@ class MachineNode(ContainerNode): else: # Global profile. groups_by_name[name].metadata_for_global = quality_changes - quality_groups = self.getQualityGroups(variant_names, material_bases, extruder_enabled) - for quality_changes_group in groups_by_name.values(): - if quality_changes_group.quality_type not in quality_groups: - quality_changes_group.is_available = False - else: - # Quality changes group is available iff the quality group it depends on is available. Irrespective of whether the intent category is available. - quality_changes_group.is_available = quality_groups[quality_changes_group.quality_type].is_available - return list(groups_by_name.values()) ## Gets the preferred global quality node, going by the preferred quality diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py index adaa4309b7..1d30b1753e 100644 --- a/cura/Machines/Models/QualityManagementModel.py +++ b/cura/Machines/Models/QualityManagementModel.py @@ -13,6 +13,7 @@ from cura.Settings.ContainerManager import ContainerManager from cura.Machines.ContainerTree import ContainerTree from cura.Settings.cura_empty_instance_containers import empty_quality_changes_container from cura.Settings.IntentManager import IntentManager +from cura.Machines.Models.MachineModelUtils import fetchLayerHeight from UM.i18n import i18nCatalog catalog = i18nCatalog("cura") @@ -295,6 +296,8 @@ class QualityManagementModel(ListModel): if not quality_group.is_available: continue + layer_height = fetchLayerHeight(quality_group) + item = {"name": quality_group.name, "is_read_only": True, "quality_group": quality_group, @@ -302,10 +305,11 @@ class QualityManagementModel(ListModel): "quality_changes_group": None, "intent_category": "default", "section_name": catalog.i18nc("@label", "Default"), + "layer_height": layer_height, # layer_height is only used for sorting } item_list.append(item) - # Sort by quality names - item_list = sorted(item_list, key = lambda x: x["name"].upper()) + # Sort by layer_height for built-in qualities + item_list = sorted(item_list, key = lambda x: x["layer_height"]) # Create intent items (non-default) available_intent_list = IntentManager.getInstance().getCurrentAvailableIntents() diff --git a/cura/Machines/VariantNode.py b/cura/Machines/VariantNode.py index fa0c61bd3d..27e359afb1 100644 --- a/cura/Machines/VariantNode.py +++ b/cura/Machines/VariantNode.py @@ -84,7 +84,7 @@ class VariantNode(ContainerNode): return material_node # First fallback: Choose any material with matching diameter. for material_node in self.materials.values(): - if approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")): + if material_node.getMetaDataEntry("approximate_diameter") and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")): return material_node fallback = next(iter(self.materials.values())) # Should only happen with empty material node. Logger.log("w", "Could not find preferred material {preferred_material} with diameter {diameter} for variant {variant_id}, falling back to {fallback}.".format( diff --git a/cura/PrinterOutput/Models/MaterialOutputModel.py b/cura/PrinterOutput/Models/MaterialOutputModel.py index 7a17ef3cce..3714824a89 100644 --- a/cura/PrinterOutput/Models/MaterialOutputModel.py +++ b/cura/PrinterOutput/Models/MaterialOutputModel.py @@ -34,3 +34,11 @@ class MaterialOutputModel(QObject): @pyqtProperty(str, constant = True) def name(self) -> str: return self._name + + def __eq__(self, other): + if self is other: + return True + if type(other) is not MaterialOutputModel: + return False + + return self.guid == other.guid and self.type == other.type and self.brand == other.brand and self.color == other.color and self.name == other.name diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index f2f6277e6a..17daaf205a 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -131,6 +131,14 @@ class GlobalStack(CuraContainerStack): return "machine_stack" return configuration_type + def getIntentCategory(self) -> str: + intent_category = "default" + for extruder in self.extruderList: + category = extruder.intent.getMetaDataEntry("intent_category", "default") + if category != "default" and category != intent_category: + intent_category = category + return intent_category + def getBuildplateName(self) -> Optional[str]: name = None if self.variant.getId() != "empty_variant": diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 1bbe2ad72a..5985234442 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -95,7 +95,6 @@ class MachineManager(QObject): extruder_manager.activeExtruderChanged.connect(self.activeQualityChanged) self.globalContainerChanged.connect(self.activeStackChanged) - self.globalValueChanged.connect(self.activeStackValueChanged) ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeStackChanged) self.activeStackChanged.connect(self.activeStackValueChanged) @@ -143,7 +142,6 @@ class MachineManager(QObject): activeStackChanged = pyqtSignal() # Emitted whenever the active extruder stack is changed (ie: when changing between extruders, changing a profile, but not when changing a value) extruderChanged = pyqtSignal() - globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed. activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed. activeStackValidationChanged = pyqtSignal() # Emitted whenever a validation inside active container is changed stacksValidationChanged = pyqtSignal() # Emitted whenever a validation is changed @@ -156,7 +154,6 @@ class MachineManager(QObject): printerConnectedStatusChanged = pyqtSignal() # Emitted every time the active machine change or the outputdevices change rootMaterialChanged = pyqtSignal() - discoveredPrintersChanged = pyqtSignal() def setInitialActiveMachine(self) -> None: active_machine_id = self._application.getPreferences().getValue("cura/active_machine") @@ -182,9 +179,11 @@ class MachineManager(QObject): # Create the configuration model with the current data in Cura self._current_printer_configuration.printerType = self._global_container_stack.definition.getName() - self._current_printer_configuration.extruderConfigurations = [] - for extruder in self._global_container_stack.extruderList: - extruder_configuration = ExtruderConfigurationModel() + + if len(self._current_printer_configuration.extruderConfigurations) != len(self._global_container_stack.extruderList): + self._current_printer_configuration.extruderConfigurations = [ExtruderConfigurationModel() for extruder in self._global_container_stack.extruderList] + + for extruder, extruder_configuration in zip(self._global_container_stack.extruderList, self._current_printer_configuration.extruderConfigurations): # For compare just the GUID is needed at this moment mat_type = extruder.material.getMetaDataEntry("material") if extruder.material != empty_material_container else None mat_guid = extruder.material.getMetaDataEntry("GUID") if extruder.material != empty_material_container else None @@ -196,7 +195,6 @@ class MachineManager(QObject): extruder_configuration.position = int(extruder.getMetaDataEntry("position")) extruder_configuration.material = material_model extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != empty_variant_container else None - self._current_printer_configuration.extruderConfigurations.append(extruder_configuration) # An empty build plate configuration from the network printer is presented as an empty string, so use "" for an # empty build plate. @@ -623,7 +621,10 @@ class MachineManager(QObject): global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack() if not global_container_stack: return False - return Util.parseBool(global_container_stack.quality.getMetaDataEntry("is_experimental", False)) + active_quality_group = self.activeQualityGroup() + if active_quality_group is None: + return False + return active_quality_group.is_experimental @pyqtProperty(str, notify = activeIntentChanged) def activeIntentCategory(self) -> str: @@ -631,13 +632,7 @@ class MachineManager(QObject): if not global_container_stack: return "" - intent_category = "default" - for extruder in global_container_stack.extruderList: - category = extruder.intent.getMetaDataEntry("intent_category", "default") - if category != "default" and category != intent_category: - intent_category = category - - return intent_category + return global_container_stack.getIntentCategory() # Provies a list of extruder positions that have a different intent from the active one. @pyqtProperty("QStringList", notify=activeIntentChanged) @@ -1115,21 +1110,6 @@ class MachineManager(QObject): def currentRootMaterialId(self) -> Dict[str, str]: return self._current_root_material_id - ## Return the variant names in the extruder stack(s). - ## For the variant in the global stack, use activeVariantBuildplateName - @pyqtProperty("QVariant", notify = activeVariantChanged) - def activeVariantNames(self) -> Dict[str, str]: - result = {} - - active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - for stack in active_stacks: - variant_container = stack.variant - position = stack.getMetaDataEntry("position") - if variant_container and variant_container != empty_variant_container: - result[position] = variant_container.getName() - - return result - # Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers # for all stacks in the currently active machine. # @@ -1456,6 +1436,8 @@ class MachineManager(QObject): else: machine_node = ContainerTree.getInstance().machines.get(self._global_container_stack.definition.getId()) variant_node = machine_node.variants.get(extruder_configuration.hotendID) + if variant_node is None: + continue self._setVariantNode(position, variant_node) # Find the material profile that the printer has stored. @@ -1536,7 +1518,8 @@ class MachineManager(QObject): if self._global_container_stack is None: return machine_definition_id = self._global_container_stack.definition.id - variant_node = self._variant_manager.getVariantNode(machine_definition_id, variant_name) + machine_node = ContainerTree.getInstance().machines.get(machine_definition_id) + variant_node = machine_node.variants.get(variant_name) self.setVariant(position, variant_node) @pyqtSlot(str, "QVariant") diff --git a/plugins/AMFReader/AMFReader.py b/plugins/AMFReader/AMFReader.py index d35fbe3d40..6c5ee91e87 100644 --- a/plugins/AMFReader/AMFReader.py +++ b/plugins/AMFReader/AMFReader.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019 fieldOfView +# Copyright (c) 2019 fieldOfView, Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. # This AMF parser is based on the AMF parser in legacy cura: @@ -39,9 +39,9 @@ class AMFReader(MeshReader): MimeTypeDatabase.addMimeType( MimeType( - name="application/x-amf", - comment="AMF", - suffixes=["amf"] + name = "application/x-amf", + comment = "AMF", + suffixes = ["amf"] ) ) @@ -94,7 +94,7 @@ class AMFReader(MeshReader): if t.tag == "x": v[0] = float(t.text) * scale elif t.tag == "y": - v[2] = float(t.text) * scale + v[2] = -float(t.text) * scale elif t.tag == "z": v[1] = float(t.text) * scale amf_mesh_vertices.append(v) @@ -114,7 +114,7 @@ class AMFReader(MeshReader): f[2] = int(t.text) indices.append(f) - mesh = trimesh.base.Trimesh(vertices=numpy.array(amf_mesh_vertices, dtype=numpy.float32), faces=numpy.array(indices, dtype=numpy.int32)) + mesh = trimesh.base.Trimesh(vertices = numpy.array(amf_mesh_vertices, dtype = numpy.float32), faces = numpy.array(indices, dtype = numpy.int32)) mesh.merge_vertices() mesh.remove_unreferenced_vertices() mesh.fix_normals() @@ -123,7 +123,7 @@ class AMFReader(MeshReader): new_node = CuraSceneNode() new_node.setSelectable(True) new_node.setMeshData(mesh_data) - new_node.setName(base_name if len(nodes)==0 else "%s %d" % (base_name, len(nodes))) + new_node.setName(base_name if len(nodes) == 0 else "%s %d" % (base_name, len(nodes))) new_node.addDecorator(BuildPlateDecorator(CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate)) new_node.addDecorator(SliceableObjectDecorator()) @@ -165,9 +165,9 @@ class AMFReader(MeshReader): indices.append(face) face_count += 1 - vertices = numpy.asarray(vertices, dtype=numpy.float32) - indices = numpy.asarray(indices, dtype=numpy.int32) + vertices = numpy.asarray(vertices, dtype = numpy.float32) + indices = numpy.asarray(indices, dtype = numpy.int32) normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count) - mesh_data = MeshData(vertices=vertices, indices=indices, normals=normals) + mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals) return mesh_data diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 9308719227..acab445fd6 100755 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -174,6 +174,7 @@ class SliceInfo(QObject, Extension): extruder_dict["extruder_settings"] = extruder_settings data["extruders"].append(extruder_dict) + data["intent_category"] = global_stack.getIntentCategory() data["quality_profile"] = global_stack.quality.getMetaData().get("quality_type") data["user_modified_setting_keys"] = self._getUserModifiedSettingKeys() diff --git a/plugins/SliceInfoPlugin/example_data.html b/plugins/SliceInfoPlugin/example_data.html index 4294b0af6d..103eb55a6a 100644 --- a/plugins/SliceInfoPlugin/example_data.html +++ b/plugins/SliceInfoPlugin/example_data.html @@ -4,6 +4,7 @@ Operating System: Windows 10
Language: en_US
Machine Type: Ultimaker S5
+ Intent Profile: Default
Quality Profile: Fast
Using Custom Settings: No diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 7dfa6483d2..fe0f73f2b3 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -87,7 +87,6 @@ class XmlMaterialProfile(InstanceContainer): container.metaDataChanged.emit(container) for k, v in new_setting_values_dict.items(): self.setProperty(k, "value", v) - return ## Overridden from InstanceContainer, similar to setMetaDataEntry. # without this function the setName would only set the name of the specific nozzle / material / machine combination container diff --git a/resources/definitions/Mark2_for_Ultimaker2.def.json b/resources/definitions/Mark2_for_Ultimaker2.def.json index 5aada425fd..b02dc78adf 100644 --- a/resources/definitions/Mark2_for_Ultimaker2.def.json +++ b/resources/definitions/Mark2_for_Ultimaker2.def.json @@ -209,10 +209,10 @@ "enabled": false }, "prime_tower_position_x": { - "default_value": 185 + "value": "185" }, "prime_tower_position_y": { - "default_value": 160 + "value": "160" }, "machine_disallowed_areas": { "default_value": [ diff --git a/resources/definitions/bibo2_dual.def.json b/resources/definitions/bibo2_dual.def.json index dbfb03a0c9..0197426ac6 100644 --- a/resources/definitions/bibo2_dual.def.json +++ b/resources/definitions/bibo2_dual.def.json @@ -85,10 +85,10 @@ "default_value": 2 }, "prime_tower_position_x": { - "default_value": 50 + "value": "50" }, "prime_tower_position_y": { - "default_value": 50 + "value": "50" } } } diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json index 3ceae8d63f..d100cd1ba9 100644 --- a/resources/definitions/builder_premium_large.def.json +++ b/resources/definitions/builder_premium_large.def.json @@ -50,8 +50,8 @@ "speed_wall_0": { "value": "math.ceil(speed_wall * 20 / 25)" }, "speed_wall_x": { "value": "speed_wall" }, - "prime_tower_position_x": { "default_value": 175 }, - "prime_tower_position_y": { "default_value": 178 }, + "prime_tower_position_x": { "value": "175" }, + "prime_tower_position_y": { "value": "178" }, "prime_tower_wipe_enabled": { "default_value": false }, "prime_tower_min_volume": { "default_value": 50 }, diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json index 5f608ba2a8..16aeeffdae 100644 --- a/resources/definitions/builder_premium_medium.def.json +++ b/resources/definitions/builder_premium_medium.def.json @@ -50,8 +50,8 @@ "speed_wall_0": { "value": "math.ceil(speed_wall * 20 / 25)" }, "speed_wall_x": { "value": "speed_wall" }, - "prime_tower_position_x": { "default_value": 175 }, - "prime_tower_position_y": { "default_value": 178 }, + "prime_tower_position_x": { "value": "175" }, + "prime_tower_position_y": { "value": "178" }, "prime_tower_wipe_enabled": { "default_value": false }, "prime_tower_min_volume": { "default_value": 50 }, diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json index a19773ec05..290e79660f 100644 --- a/resources/definitions/builder_premium_small.def.json +++ b/resources/definitions/builder_premium_small.def.json @@ -49,8 +49,8 @@ "speed_wall_0": { "value": "math.ceil(speed_wall * 20 / 25)" }, "speed_wall_x": { "value": "speed_wall" }, - "prime_tower_position_x": { "default_value": 175 }, - "prime_tower_position_y": { "default_value": 178 }, + "prime_tower_position_x": { "value": "175" }, + "prime_tower_position_y": { "value": "178" }, "prime_tower_wipe_enabled": { "default_value": false }, "prime_tower_min_volume": { "default_value": 50 }, diff --git a/resources/definitions/cartesio.def.json b/resources/definitions/cartesio.def.json index 4ed1a9f2d9..e7a005682d 100644 --- a/resources/definitions/cartesio.def.json +++ b/resources/definitions/cartesio.def.json @@ -44,8 +44,8 @@ "prime_tower_enable": { "default_value": false }, "prime_tower_min_volume": { "value": "0.7" }, "prime_tower_size": { "value": 24.0 }, - "prime_tower_position_x": { "value": 125 }, - "prime_tower_position_y": { "value": 70 }, + "prime_tower_position_x": { "value": "125" }, + "prime_tower_position_y": { "value": "70" }, "prime_blob_enable": { "default_value": false }, "machine_max_feedrate_z": { "default_value": 20 }, "machine_disallowed_areas": { "default_value": [ diff --git a/resources/definitions/creality_base.def.json b/resources/definitions/creality_base.def.json index d7e028f31a..7e91fb4989 100644 --- a/resources/definitions/creality_base.def.json +++ b/resources/definitions/creality_base.def.json @@ -125,7 +125,7 @@ "overrides": { "machine_name": { "default_value": "Creawsome Base Printer" }, "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n" }, - "machine_end_gcode": { "default_value": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y{machine_depth} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" }, + "machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y{machine_depth} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" }, "machine_max_feedrate_x": { "value": 500 }, "machine_max_feedrate_y": { "value": 500 }, diff --git a/resources/definitions/creality_ender5.def.json b/resources/definitions/creality_ender5.def.json index d95f4a1467..c1511884ae 100644 --- a/resources/definitions/creality_ender5.def.json +++ b/resources/definitions/creality_ender5.def.json @@ -4,7 +4,7 @@ "inherits": "creality_base", "overrides": { "machine_name": { "default_value": "Creality Ender-5" }, - "machine_end_gcode": { "default_value": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" }, + "machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG1 X0 Y0 ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z\n" }, "machine_width": { "default_value": 220 }, "machine_depth": { "default_value": 220 }, "machine_height": { "default_value": 300 }, diff --git a/resources/definitions/raise3D_N2_dual.def.json b/resources/definitions/raise3D_N2_dual.def.json index 1994cc2bcb..530ad79d19 100644 --- a/resources/definitions/raise3D_N2_dual.def.json +++ b/resources/definitions/raise3D_N2_dual.def.json @@ -76,10 +76,10 @@ "default_value": 2 }, "prime_tower_position_x": { - "default_value": 195 + "value": "195" }, "prime_tower_position_y": { - "default_value": 149 + "value": "149" } } } diff --git a/resources/definitions/raise3D_N2_plus_dual.def.json b/resources/definitions/raise3D_N2_plus_dual.def.json index 23ad1fbd09..ffc4afec16 100644 --- a/resources/definitions/raise3D_N2_plus_dual.def.json +++ b/resources/definitions/raise3D_N2_plus_dual.def.json @@ -76,10 +76,10 @@ "default_value": 2 }, "prime_tower_position_x": { - "default_value": 195 + "value": "195" }, "prime_tower_position_y": { - "default_value": 149 + "value": "149" } } } diff --git a/resources/definitions/raise3D_N2_plus_single.def.json b/resources/definitions/raise3D_N2_plus_single.def.json index f8a1a7e0fb..ccb169efb1 100644 --- a/resources/definitions/raise3D_N2_plus_single.def.json +++ b/resources/definitions/raise3D_N2_plus_single.def.json @@ -72,10 +72,10 @@ "default_value": "M107\nM1002\nM104 S0 T1\nM104 S0 T0\nM140 S0\nM117 Print Complete.\nG28 X0 Y0\nG91\nG1 Z10\nG90\nM84" }, "prime_tower_position_x": { - "default_value": 195 + "value": "195" }, "prime_tower_position_y": { - "default_value": 149 + "value": "149" } } } diff --git a/resources/definitions/raise3D_N2_single.def.json b/resources/definitions/raise3D_N2_single.def.json index c69823466b..f0915d1a31 100644 --- a/resources/definitions/raise3D_N2_single.def.json +++ b/resources/definitions/raise3D_N2_single.def.json @@ -72,10 +72,10 @@ "default_value": "M107\nM1002\nM104 S0 T1\nM104 S0 T0\nM140 S0\nM117 Print Complete.\nG28 X0 Y0\nG91\nG1 Z10\nG90\nM84" }, "prime_tower_position_x": { - "default_value": 195 + "value": "195" }, "prime_tower_position_y": { - "default_value": 149 + "value": "149" } } } diff --git a/resources/definitions/ultimaker_s3.def.json b/resources/definitions/ultimaker_s3.def.json index f7f3a038fe..0d6834521e 100644 --- a/resources/definitions/ultimaker_s3.def.json +++ b/resources/definitions/ultimaker_s3.def.json @@ -68,8 +68,8 @@ "extruder_prime_pos_abs": { "default_value": true }, "machine_start_gcode": { "default_value": "" }, "machine_end_gcode": { "default_value": "" }, - "prime_tower_position_x": { "default_value": 345 }, - "prime_tower_position_y": { "default_value": 222.5 }, + "prime_tower_position_x": { "value": "345" }, + "prime_tower_position_y": { "value": "222.5" }, "prime_blob_enable": { "enabled": true, "default_value": false }, "speed_travel": diff --git a/resources/definitions/ultimaker_s5.def.json b/resources/definitions/ultimaker_s5.def.json index fef8c87c27..dfa8da5397 100644 --- a/resources/definitions/ultimaker_s5.def.json +++ b/resources/definitions/ultimaker_s5.def.json @@ -70,8 +70,8 @@ "extruder_prime_pos_abs": { "default_value": true }, "machine_start_gcode": { "default_value": "" }, "machine_end_gcode": { "default_value": "" }, - "prime_tower_position_x": { "default_value": 345 }, - "prime_tower_position_y": { "default_value": 222.5 }, + "prime_tower_position_x": { "value": "345" }, + "prime_tower_position_y": { "value": "222.5" }, "prime_blob_enable": { "enabled": true, "default_value": false }, "speed_travel": diff --git a/resources/qml/Dialogs/WorkspaceSummaryDialog.qml b/resources/qml/Dialogs/WorkspaceSummaryDialog.qml index 99a0666ee1..d698c0d3af 100644 --- a/resources/qml/Dialogs/WorkspaceSummaryDialog.qml +++ b/resources/qml/Dialogs/WorkspaceSummaryDialog.qml @@ -148,8 +148,18 @@ UM.Dialog { height: childrenRect.height width: parent.width - property string variantName: Cura.MachineManager.activeVariantNames[modelData] !== undefined ? Cura.MachineManager.activeVariantNames[modelData]: "" - property string materialName: Cura.MachineManager.getExtruder(modelData).material.name !== undefined ? Cura.MachineManager.getExtruder(modelData).material.name : "" + property string variantName: + { + var extruder = Cura.MachineManager.activeMachine.extruderList[modelData] + var variant_name = extruder.variant.name + return (variant_name !== undefined) ? variant_name : "" + } + property string materialName: + { + var extruder = Cura.MachineManager.activeMachine.extruderList[modelData] + var material_name = extruder.material.name + return (material_name !== undefined) ? material_name : "" + } Label { text: { diff --git a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml index 6f3d6ffa17..fda9ee35ac 100644 --- a/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/CustomConfiguration.qml @@ -221,6 +221,7 @@ Item OldControls.CheckBox { + id: enabledCheckbox checked: Cura.MachineManager.activeStack != null ? Cura.MachineManager.activeStack.isEnabled : false enabled: !checked || Cura.MachineManager.numberExtrudersEnabled > 1 //Disable if it's the last enabled extruder. height: parent.height @@ -265,6 +266,7 @@ Item text: Cura.MachineManager.activeStack !== null ? Cura.MachineManager.activeStack.material.name : "" tooltip: text + enabled: enabledCheckbox.checked width: selectors.controlWidth height: parent.height @@ -324,7 +326,8 @@ Item height: parent.height width: selectors.controlWidth style: UM.Theme.styles.print_setup_header_button - activeFocusOnPress: true; + activeFocusOnPress: true + enabled: enabledCheckbox.checked menu: Cura.NozzleMenu { extruderIndex: Cura.ExtruderManager.activeExtruderIndex } } diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml index 94a5262b72..7953128590 100644 --- a/resources/qml/Menus/MaterialMenu.qml +++ b/resources/qml/Menus/MaterialMenu.qml @@ -50,6 +50,7 @@ Menu { text: model.brand + " " + model.name checkable: true + enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled checked: model.root_material_id === menu.currentRootMaterialId onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) exclusiveGroup: favoriteGroup // One favorite and one item from the others can be active at the same time. @@ -72,6 +73,7 @@ Menu { text: model.name checkable: true + enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled checked: model.root_material_id === menu.currentRootMaterialId exclusiveGroup: group onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) @@ -110,6 +112,7 @@ Menu { text: model.name checkable: true + enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled checked: model.id === menu.activeMaterialId exclusiveGroup: group onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml index 3d7dd1b6c5..a291f125eb 100644 --- a/resources/qml/Menus/NozzleMenu.qml +++ b/resources/qml/Menus/NozzleMenu.qml @@ -1,7 +1,7 @@ // Copyright (c) 2017 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. -import QtQuick 2.7 +import QtQuick 2.10 import QtQuick.Controls 1.4 import UM 1.2 as UM @@ -28,10 +28,11 @@ Menu text: model.hotend_name checkable: true checked: { - return Cura.MachineManager.activeVariantNames[extruderIndex] == model.hotend_name + var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex] + return extruder.variant.name == model.hotend_name } exclusiveGroup: group - + enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled onTriggered: { Cura.MachineManager.setVariant(menu.extruderIndex, model.container_node); } diff --git a/resources/qml/Preferences/Materials/MaterialsPage.qml b/resources/qml/Preferences/Materials/MaterialsPage.qml index a8de240924..32c4773640 100644 --- a/resources/qml/Preferences/Materials/MaterialsPage.qml +++ b/resources/qml/Preferences/Materials/MaterialsPage.qml @@ -59,11 +59,14 @@ Item onCurrentItemChanged: { forceActiveFocus() - materialDetailsPanel.currentItem = currentItem - // CURA-6679 If the current item is gone after the model update, reset the current item to the active material. - if (currentItem == null) + if(materialDetailsPanel.currentItem != currentItem) { - resetExpandedActiveMaterial() + materialDetailsPanel.currentItem = currentItem + // CURA-6679 If the current item is gone after the model update, reset the current item to the active material. + if (currentItem == null) + { + resetExpandedActiveMaterial() + } } } diff --git a/resources/qml/Preferences/Materials/MaterialsView.qml b/resources/qml/Preferences/Materials/MaterialsView.qml index 0f5eba2f2f..6d5a8119c5 100644 --- a/resources/qml/Preferences/Materials/MaterialsView.qml +++ b/resources/qml/Preferences/Materials/MaterialsView.qml @@ -17,7 +17,7 @@ TabView property QtObject properties property var currentMaterialNode: null - property bool editingEnabled: false; + property bool editingEnabled: false property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€" property real firstColumnWidth: (width * 0.50) | 0 property real secondColumnWidth: (width * 0.40) | 0 diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 51fe7ac81f..dc7c3d109f 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -531,8 +531,12 @@ Item Label { + anchors.left: parent.left + anchors.right: parent.right text: base.currentItemDisplayName font: UM.Theme.getFont("large_bold") + elide: Text.ElideRight + renderType: Text.NativeRendering } } diff --git a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml index 2698089d0c..99fdafdb73 100644 --- a/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml +++ b/resources/qml/PrintSetupSelector/Custom/CustomPrintSetup.qml @@ -110,6 +110,11 @@ Item resultSuffix += " (Experimental)" } + if (Cura.MachineManager.isActiveQualityCustom) + { + result = resultMain + } + if (Cura.MachineManager.isActiveQualitySupported) { if (Cura.MachineManager.activeQualityLayerHeight > 0) diff --git a/tests/TestMachineManager.py b/tests/TestMachineManager.py index 313ada2bf0..96c0bc1bec 100644 --- a/tests/TestMachineManager.py +++ b/tests/TestMachineManager.py @@ -99,18 +99,6 @@ def test_allActiveMaterialIds(machine_manager, extruder_manager): assert machine_manager.allActiveMaterialIds == {"extruder_1": "material_1", "extruder_2": "material_2"} -def test_activeVariantNames(machine_manager, extruder_manager): - extruder_1 = createMockedExtruder("extruder_1") - extruder_2 = createMockedExtruder("extruder_2") - extruder_1.getMetaDataEntry = MagicMock(return_value = "0") - extruder_2.getMetaDataEntry = MagicMock(return_value= "2") - extruder_1.variant = createMockedInstanceContainer("variant_1", "variant_name_1") - extruder_2.variant = createMockedInstanceContainer("variant_2", "variant_name_2") - extruder_manager.getActiveExtruderStacks = MagicMock(return_value=[extruder_1, extruder_2]) - - assert machine_manager.activeVariantNames == {"0": "variant_name_1", "2": "variant_name_2"} - - def test_globalVariantName(machine_manager, application): global_stack = application.getGlobalContainerStack() global_stack.variant = createMockedInstanceContainer("beep", "zomg")