mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-21 05:37:50 -06:00
Merge branch 'feature_intent' of github.com:Ultimaker/Cura into feature_intent
This commit is contained in:
commit
b3b28bc330
21 changed files with 266 additions and 118 deletions
|
@ -8,6 +8,7 @@ from UM.Signal import Signal
|
|||
from UM.Util import parseBool
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry # To find all the variants for this machine.
|
||||
|
||||
import cura.CuraApplication # Imported like this to prevent circular dependencies.
|
||||
from cura.Machines.ContainerNode import ContainerNode
|
||||
from cura.Machines.QualityChangesGroup import QualityChangesGroup # To construct groups of quality changes profiles that belong together.
|
||||
from cura.Machines.QualityGroup import QualityGroup # To construct groups of quality profiles that belong together.
|
||||
|
@ -74,7 +75,7 @@ class MachineNode(ContainerNode):
|
|||
qualities_per_type_per_extruder[extruder_nr] = self.global_qualities
|
||||
else:
|
||||
# Use the actually specialised quality profiles.
|
||||
qualities_per_type_per_extruder[extruder_nr] = {node.getMetaDataEntry("quality_type"): node for node in self.variants[variant_name].materials[material_base].qualities.values()}
|
||||
qualities_per_type_per_extruder[extruder_nr] = {node.quality_type: node for node in self.variants[variant_name].materials[material_base].qualities.values()}
|
||||
|
||||
# Create the quality group for each available type.
|
||||
quality_groups = {}
|
||||
|
@ -82,15 +83,7 @@ class MachineNode(ContainerNode):
|
|||
if not global_quality_node.container:
|
||||
Logger.log("w", "Node {0} doesn't have a container.".format(global_quality_node.container_id))
|
||||
continue
|
||||
# CURA-6599
|
||||
# Same as QualityChangesGroup.
|
||||
# For some reason, QML will get null or fail to convert type for MachineManager.activeQualityChangesGroup() to
|
||||
# a QObject. Setting the object ownership to QQmlEngine.CppOwnership doesn't work, but setting the object
|
||||
# parent to application seems to work.
|
||||
from cura.CuraApplication import CuraApplication
|
||||
quality_groups[quality_type] = QualityGroup(name = global_quality_node.container.getMetaDataEntry("name", "Unnamed profile"),
|
||||
quality_type = quality_type,
|
||||
parent = CuraApplication.getInstance())
|
||||
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):
|
||||
if quality_type in qualities_per_type:
|
||||
|
@ -170,7 +163,7 @@ class MachineNode(ContainerNode):
|
|||
|
||||
## (Re)loads all variants under this printer.
|
||||
@UM.FlameProfiler.profile
|
||||
def _loadAll(self):
|
||||
def _loadAll(self) -> None:
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
if not self.has_variants:
|
||||
self.variants["empty"] = VariantNode("empty_variant", machine = self)
|
||||
|
@ -190,4 +183,4 @@ class MachineNode(ContainerNode):
|
|||
if len(global_qualities) == 0: # This printer doesn't override the global qualities.
|
||||
global_qualities = container_registry.findInstanceContainersMetadata(type = "quality", definition = "fdmprinter", global_quality = "True") # Otherwise pick the global global qualities.
|
||||
for global_quality in global_qualities:
|
||||
self.global_qualities[global_quality["quality_type"]] = QualityNode(global_quality["id"], parent = self)
|
||||
self.global_qualities[global_quality["quality_type"]] = QualityNode(global_quality["id"], parent = self)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import Dict, Optional, List, Set
|
||||
|
@ -11,24 +11,28 @@ from UM.Util import parseBool
|
|||
from cura.Machines.ContainerNode import ContainerNode
|
||||
|
||||
|
||||
## A QualityGroup represents a group of quality containers that must be applied
|
||||
# to each ContainerStack when it's used.
|
||||
#
|
||||
# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used.
|
||||
# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type
|
||||
# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3
|
||||
# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look
|
||||
# as below:
|
||||
# GlobalStack ExtruderStack 1 ExtruderStack 2
|
||||
# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal
|
||||
# A concrete example: When there are two extruders and the user selects the
|
||||
# quality type "normal", this quality type must be applied to all stacks in a
|
||||
# machine, although each stack can have different containers. So one global
|
||||
# profile gets put on the global stack and one extruder profile gets put on
|
||||
# each extruder stack. This quality group then contains the following
|
||||
# profiles (for instance):
|
||||
# GlobalStack ExtruderStack 1 ExtruderStack 2
|
||||
# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal
|
||||
#
|
||||
# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to
|
||||
# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead
|
||||
# of looking them up again.
|
||||
#
|
||||
class QualityGroup(QObject):
|
||||
|
||||
def __init__(self, name: str, quality_type: str, parent: Optional["QObject"] = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
||||
# The purpose of these quality groups is to group the containers that can be
|
||||
# applied to a configuration, so that when a quality level is selected, the
|
||||
# container can directly be applied to each stack instead of looking them up
|
||||
# again.
|
||||
class QualityGroup:
|
||||
## Constructs a new group.
|
||||
# \param name The user-visible name for the group.
|
||||
# \param quality_type The quality level that each profile in this group
|
||||
# has.
|
||||
def __init__(self, name: str, quality_type: str) -> None:
|
||||
self.name = name
|
||||
self.node_for_global = None # type: Optional[ContainerNode]
|
||||
self.nodes_for_extruders = {} # type: Dict[int, ContainerNode]
|
||||
|
@ -36,7 +40,6 @@ class QualityGroup(QObject):
|
|||
self.is_available = False
|
||||
self.is_experimental = False
|
||||
|
||||
@pyqtSlot(result = str)
|
||||
def getName(self) -> str:
|
||||
return self.name
|
||||
|
||||
|
|
|
@ -111,14 +111,7 @@ class QualityManager(QObject):
|
|||
quality_group_dict = dict()
|
||||
for node in nodes_to_check:
|
||||
if node and node.quality_type:
|
||||
# CURA-6599
|
||||
# Same as QualityChangesGroup.
|
||||
# For some reason, QML will get null or fail to convert type for MachineManager.activeQualityChangesGroup() to
|
||||
# a QObject. Setting the object ownership to QQmlEngine.CppOwnership doesn't work, but setting the object
|
||||
# parent to application seems to work.
|
||||
from cura.CuraApplication import CuraApplication
|
||||
quality_group = QualityGroup(node.getMetaDataEntry("name", ""), node.quality_type,
|
||||
parent = CuraApplication.getInstance())
|
||||
quality_group = QualityGroup(node.getMetaDataEntry("name", ""), node.quality_type)
|
||||
quality_group.setGlobalNode(node)
|
||||
quality_group_dict[node.quality_type] = quality_group
|
||||
|
||||
|
|
|
@ -123,6 +123,14 @@ class MachineManager(QObject):
|
|||
self.globalContainerChanged.connect(self.printerConnectedStatusChanged)
|
||||
self.outputDevicesChanged.connect(self.printerConnectedStatusChanged)
|
||||
|
||||
# For updating active quality display name
|
||||
self.activeQualityChanged.connect(self.activeQualityDisplayNameChanged)
|
||||
self.activeIntentChanged.connect(self.activeQualityDisplayNameChanged)
|
||||
self.activeQualityGroupChanged.connect(self.activeQualityDisplayNameChanged)
|
||||
self.activeQualityChangesGroupChanged.connect(self.activeQualityDisplayNameChanged)
|
||||
|
||||
activeQualityDisplayNameChanged = pyqtSignal()
|
||||
|
||||
activeQualityGroupChanged = pyqtSignal()
|
||||
activeQualityChangesGroupChanged = pyqtSignal()
|
||||
|
||||
|
@ -605,9 +613,10 @@ class MachineManager(QObject):
|
|||
global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if not global_container_stack:
|
||||
return False
|
||||
if not self.activeQualityGroup:
|
||||
active_quality_group = self.activeQualityGroup()
|
||||
if active_quality_group is None:
|
||||
return False
|
||||
return self.activeQualityGroup.is_available
|
||||
return active_quality_group.is_available
|
||||
|
||||
@pyqtProperty(bool, notify = activeQualityGroupChanged)
|
||||
def isActiveQualityExperimental(self) -> bool:
|
||||
|
@ -629,16 +638,6 @@ class MachineManager(QObject):
|
|||
intent_category = category
|
||||
return intent_category
|
||||
|
||||
# Returns the human-readable name of the active intent category. If the intent category is "default", returns an
|
||||
# empty string.
|
||||
@pyqtProperty(str, notify = activeIntentChanged)
|
||||
def activeIntentName(self) -> str:
|
||||
intent_category = self.activeIntentCategory
|
||||
if intent_category == "default":
|
||||
intent_category = ""
|
||||
intent_name = intent_category.capitalize()
|
||||
return intent_name
|
||||
|
||||
# Provies a list of extruder positions that have a different intent from the active one.
|
||||
@pyqtProperty("QStringList", notify=activeIntentChanged)
|
||||
def extruderPositionsWithNonActiveIntent(self):
|
||||
|
@ -1591,6 +1590,34 @@ class MachineManager(QObject):
|
|||
if not no_dialog and self.hasUserSettings and self._application.getPreferences().getValue("cura/active_mode") == 1:
|
||||
self._application.discardOrKeepProfileChanges()
|
||||
|
||||
# The display name of currently active quality.
|
||||
# This display name is:
|
||||
# - For built-in qualities (quality/intent): the quality type name, such as "Fine", "Normal", etc.
|
||||
# - For custom qualities: <custom_quality_name> - <intent_name> - <quality_type_name>
|
||||
# Examples:
|
||||
# - "my_profile - Fine" (only based on a default quality, no intent involved)
|
||||
# - "my_profile - Engineering - Fine" (based on an intent)
|
||||
@pyqtProperty(str, notify = activeQualityDisplayNameChanged)
|
||||
def activeQualityDisplayName(self) -> str:
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if global_stack is None:
|
||||
return ""
|
||||
|
||||
# Not a custom quality
|
||||
display_name = self.activeQualityOrQualityChangesName
|
||||
if global_stack.qualityChanges == empty_quality_changes_container:
|
||||
return display_name
|
||||
|
||||
# A custom quality
|
||||
intent_category = self.activeIntentCategory
|
||||
if intent_category != "default":
|
||||
from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
|
||||
intent_display_name = IntentCategoryModel.name_translation.get(intent_category, catalog.i18nc("@label", "Unknown"))
|
||||
display_name += " - {intent_name}".format(intent_name = intent_display_name)
|
||||
|
||||
display_name += " - {quality_level_name}".format(quality_level_name = global_stack.quality.getName())
|
||||
return display_name
|
||||
|
||||
## Change the intent category of the current printer.
|
||||
#
|
||||
# All extruders can change their profiles. If an intent profile is
|
||||
|
@ -1620,13 +1647,26 @@ class MachineManager(QObject):
|
|||
else: # No intent had the correct category.
|
||||
extruder.intent = empty_intent_container
|
||||
|
||||
@pyqtProperty(QObject, fset = setQualityGroup, notify = activeQualityGroupChanged)
|
||||
## Get the currently activated quality group.
|
||||
#
|
||||
# If no printer is added yet or the printer doesn't have quality profiles,
|
||||
# this returns ``None``.
|
||||
# \return The currently active quality group.
|
||||
def activeQualityGroup(self) -> Optional["QualityGroup"]:
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if not global_stack or global_stack.quality == empty_quality_container:
|
||||
return None
|
||||
return ContainerTree.getInstance().getCurrentQualityGroups().get(self.activeQualityType)
|
||||
|
||||
## Get the name of the active quality group.
|
||||
# \return The name of the active quality group.
|
||||
@pyqtProperty(str, notify = activeQualityGroupChanged)
|
||||
def activeQualityGroupName(self) -> str:
|
||||
quality_group = self.activeQualityGroup()
|
||||
if quality_group is None:
|
||||
return ""
|
||||
return quality_group.getName()
|
||||
|
||||
@pyqtSlot(QObject)
|
||||
def setQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", no_dialog: bool = False) -> None:
|
||||
self.blurSettings.emit()
|
||||
|
@ -1642,7 +1682,7 @@ class MachineManager(QObject):
|
|||
if self._global_container_stack is None:
|
||||
return
|
||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||
self._setQualityGroup(self.activeQualityGroup)
|
||||
self._setQualityGroup(self.activeQualityGroup())
|
||||
for stack in [self._global_container_stack] + list(self._global_container_stack.extruders.values()):
|
||||
stack.userChanges.clear()
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ variant = AA 0.4
|
|||
speed_infill = =speed_print
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
speed_layer_0 = 20
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_thickness = =line_width * 2
|
||||
|
@ -25,8 +26,9 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
wall_line_width_x = =line_width
|
||||
|
|
|
@ -16,14 +16,18 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
speed_layer_0 = 20
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = =line_width * 3
|
||||
|
|
|
@ -16,14 +16,18 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
speed_layer_0 = 20
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = =line_width * 3
|
||||
|
|
|
@ -12,21 +12,23 @@ material = generic_pla
|
|||
variant = AA 0.4
|
||||
|
||||
[values]
|
||||
speed_infill = =speed_print
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
speed_layer_0 = 20
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_thickness = =line_width * 2
|
||||
infill_sparse_density = 15
|
||||
fill_perimeter_gaps = nowhere
|
||||
infill_sparse_density = 15
|
||||
infill_line_width = =line_width
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
speed_infill = =speed_print
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_layer_0 = 20
|
||||
wall_line_width_x = =line_width
|
||||
|
|
|
@ -16,14 +16,18 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
speed_layer_0 = 20
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = =line_width * 3
|
||||
|
|
|
@ -16,14 +16,18 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
speed_layer_0 = 20
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = =line_width * 3
|
||||
|
|
|
@ -15,7 +15,8 @@ variant = AA 0.4
|
|||
speed_infill = =speed_print
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
speed_layer_0 = 20
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_thickness = =line_width * 2
|
||||
|
@ -25,8 +26,9 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
wall_line_width_x = =line_width
|
||||
|
|
|
@ -16,14 +16,18 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
speed_layer_0 = 20
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = =line_width * 3
|
||||
|
|
|
@ -16,14 +16,18 @@ infill_line_width = =line_width
|
|||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall_0 = =jerk_print
|
||||
jerk_wall_x = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
line_width = =machine_nozzle_size
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
speed_layer_0 = 20
|
||||
speed_topbottom = =speed_print
|
||||
speed_wall = =speed_print
|
||||
speed_wall_0 = =speed_print
|
||||
speed_wall_0 = =speed_wall
|
||||
speed_wall_x = =speed_wall
|
||||
top_bottom_thickness = =wall_thickness
|
||||
wall_line_width_x = =line_width
|
||||
wall_thickness = =line_width * 3
|
||||
|
|
|
@ -7,7 +7,7 @@ import QtQuick.Layouts 1.3
|
|||
|
||||
import UM 1.2 as UM
|
||||
|
||||
// The labelBar shows a set of labels that are evenly spaced from oneother.
|
||||
// The labelBar shows a set of labels that are evenly spaced from one another.
|
||||
// The first item is aligned to the left, the last is aligned to the right.
|
||||
// It's intended to be used together with RadioCheckBar. As such, it needs
|
||||
// to know what the used itemSize is, so it can ensure the labels are aligned correctly.
|
||||
|
|
|
@ -100,17 +100,7 @@ Item
|
|||
|
||||
function generateActiveQualityText()
|
||||
{
|
||||
var result = Cura.MachineManager.activeQualityOrQualityChangesName
|
||||
|
||||
// If this is a custom quality, add intent (if present) and quality it is based on
|
||||
if (Cura.MachineManager.isActiveQualityCustom)
|
||||
{
|
||||
if (Cura.MachineManager.activeIntentName != "")
|
||||
{
|
||||
result += " - " + Cura.MachineManager.activeIntentName
|
||||
}
|
||||
result += " - " + Cura.MachineManager.activeQualityGroup.getName()
|
||||
}
|
||||
var result = Cura.MachineManager.activeQualityDisplayName
|
||||
|
||||
if (Cura.MachineManager.isActiveQualityExperimental)
|
||||
{
|
||||
|
|
|
@ -20,17 +20,7 @@ RowLayout
|
|||
{
|
||||
if (Cura.MachineManager.activeStack)
|
||||
{
|
||||
var text = Cura.MachineManager.activeQualityOrQualityChangesName
|
||||
|
||||
// If this is a custom quality, add intent (if present) and quality it is based on
|
||||
if (Cura.MachineManager.isActiveQualityCustom)
|
||||
{
|
||||
if (Cura.MachineManager.activeIntentName != "")
|
||||
{
|
||||
text += " - " + Cura.MachineManager.activeIntentName
|
||||
}
|
||||
text += " - " + Cura.MachineManager.activeQualityGroup.getName()
|
||||
}
|
||||
var text = Cura.MachineManager.activeQualityDisplayName
|
||||
|
||||
if (!Cura.MachineManager.hasNotSupportedQuality)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
|
@ -9,6 +9,7 @@ import QtQuick.Controls.Styles 1.4
|
|||
import UM 1.2 as UM
|
||||
import Cura 1.6 as Cura
|
||||
import ".."
|
||||
|
||||
Item
|
||||
{
|
||||
id: qualityRow
|
||||
|
|
|
@ -19,7 +19,7 @@ Item
|
|||
property int barSize: UM.Theme.getSize("slider_groove_radius").height
|
||||
property var isCheckedFunction // Function that accepts the modelItem and returns if the item should be active.
|
||||
|
||||
implicitWidth: 200
|
||||
implicitWidth: 200 * screenScaleFactor
|
||||
implicitHeight: checkboxSize
|
||||
|
||||
property var dataModel: null
|
||||
|
@ -62,7 +62,7 @@ Item
|
|||
Layout.fillHeight: true
|
||||
// The last item of the repeater needs to be shorter, as we don't need another part to fit
|
||||
// the horizontal bar. The others should essentially not be limited.
|
||||
Layout.maximumWidth: index + 1 === repeater.count ? activeComponent.width: 200000000
|
||||
Layout.maximumWidth: index + 1 === repeater.count ? activeComponent.width : 200000000
|
||||
|
||||
property bool isEnabled: model.available
|
||||
// The horizontal bar between the checkable options.
|
||||
|
|
|
@ -23,6 +23,18 @@ def container_registry():
|
|||
result.findContainersMetadata = MagicMock(return_value = [metadata_dict])
|
||||
return result
|
||||
|
||||
## Creates a machine node without anything underneath it. No sub-nodes.
|
||||
#
|
||||
# For testing stuff with machine nodes without testing _loadAll(). You'll need
|
||||
# to add subnodes manually in your test.
|
||||
@pytest.fixture
|
||||
def empty_machine_node():
|
||||
empty_container_registry = MagicMock()
|
||||
empty_container_registry.findContainersMetadata = MagicMock(return_value = [metadata_dict]) # Still contain the MachineNode's own metadata for the constructor.
|
||||
empty_container_registry.findInstanceContainersMetadata = MagicMock(return_value = [])
|
||||
with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value = empty_container_registry)):
|
||||
with patch("cura.Machines.MachineNode.MachineNode._loadAll", MagicMock()):
|
||||
return MachineNode("machine_1")
|
||||
|
||||
def getMetadataEntrySideEffect(*args, **kwargs):
|
||||
return metadata_dict.get(args[0])
|
||||
|
@ -60,4 +72,100 @@ def test_metadataProperties(container_registry):
|
|||
assert node.exclude_materials == metadata_dict["exclude_materials"]
|
||||
assert node.preferred_variant_name == metadata_dict["preferred_variant_name"]
|
||||
assert node.preferred_material == metadata_dict["preferred_material"]
|
||||
assert node.preferred_quality_type == metadata_dict["preferred_quality_type"]
|
||||
assert node.preferred_quality_type == metadata_dict["preferred_quality_type"]
|
||||
|
||||
## Test getting quality groups when there are quality profiles available for
|
||||
# the requested configurations on two extruders.
|
||||
def test_getQualityGroupsBothExtrudersAvailable(empty_machine_node):
|
||||
# Prepare a tree inside the machine node.
|
||||
extruder_0_node = MagicMock(quality_type = "quality_type_1")
|
||||
extruder_1_node = MagicMock(quality_type = "quality_type_1") # Same quality type, so this is the one that can be returned.
|
||||
empty_machine_node.variants = {
|
||||
"variant_1": MagicMock(
|
||||
materials = {
|
||||
"material_1": MagicMock(
|
||||
qualities = {
|
||||
"quality_1": extruder_0_node
|
||||
}
|
||||
)
|
||||
}
|
||||
),
|
||||
"variant_2": MagicMock(
|
||||
materials = {
|
||||
"material_2": MagicMock(
|
||||
qualities = {
|
||||
"quality_2": extruder_1_node
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
global_node = MagicMock(
|
||||
container = MagicMock(id = "global_quality_container"), # Needs to exist, otherwise it won't add this quality type.
|
||||
getMetaDataEntry = lambda _, __: "Global Quality Profile Name"
|
||||
)
|
||||
empty_machine_node.global_qualities = {
|
||||
"quality_type_1": global_node
|
||||
}
|
||||
|
||||
# Request the quality groups for the variants in the machine tree.
|
||||
result = empty_machine_node.getQualityGroups(["variant_1", "variant_2"], ["material_1", "material_2"], [True, True])
|
||||
|
||||
assert "quality_type_1" in result, "This quality type was available for both extruders."
|
||||
assert result["quality_type_1"].node_for_global == global_node
|
||||
assert result["quality_type_1"].nodes_for_extruders[0] == extruder_0_node
|
||||
assert result["quality_type_1"].nodes_for_extruders[1] == extruder_1_node
|
||||
assert result["quality_type_1"].name == global_node.getMetaDataEntry("name", "Unnamed Profile")
|
||||
assert result["quality_type_1"].quality_type == "quality_type_1"
|
||||
|
||||
## Test the "is_available" flag on quality groups.
|
||||
#
|
||||
# If a profile is available for a quality type on an extruder but not on all
|
||||
# extruders, there should be a quality group for it but it should not be made
|
||||
# available.
|
||||
def test_getQualityGroupsAvailability(empty_machine_node):
|
||||
# Prepare a tree inside the machine node.
|
||||
extruder_0_both = MagicMock(quality_type = "quality_type_both") # This quality type is available for both extruders.
|
||||
extruder_1_both = MagicMock(quality_type = "quality_type_both")
|
||||
extruder_0_exclusive = MagicMock(quality_type = "quality_type_0") # These quality types are only available on one of the extruders.
|
||||
extruder_1_exclusive = MagicMock(quality_type = "quality_type_1")
|
||||
empty_machine_node.variants = {
|
||||
"variant_1": MagicMock(
|
||||
materials = {
|
||||
"material_1": MagicMock(
|
||||
qualities = {
|
||||
"quality_0_both": extruder_0_both,
|
||||
"quality_0_exclusive": extruder_0_exclusive
|
||||
}
|
||||
)
|
||||
}
|
||||
),
|
||||
"variant_2": MagicMock(
|
||||
materials = {
|
||||
"material_2": MagicMock(
|
||||
qualities = {
|
||||
"quality_1_both": extruder_1_both,
|
||||
"quality_1_exclusive": extruder_1_exclusive
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
global_both = MagicMock(container = MagicMock(id = "global_quality_both"), getMetaDataEntry = lambda _, __: "Global Quality Both")
|
||||
global_0 = MagicMock(container = MagicMock(id = "global_quality_0"), getMetaDataEntry = lambda _, __: "Global Quality 0 Exclusive")
|
||||
global_1 = MagicMock(container = MagicMock(id = "global_quality_1"), getMetaDataEntry = lambda _, __: "Global Quality 1 Exclusive")
|
||||
empty_machine_node.global_qualities = {
|
||||
"quality_type_both": global_both,
|
||||
"quality_type_0": global_0,
|
||||
"quality_type_1": global_1
|
||||
}
|
||||
|
||||
# Request the quality groups for the variants in the machine tree.
|
||||
result = empty_machine_node.getQualityGroups(["variant_1", "variant_2"], ["material_1", "material_2"], [True, True])
|
||||
|
||||
assert "quality_type_both" in result, "This quality type was available on both extruders."
|
||||
assert result["quality_type_both"].is_available, "This quality type was available on both extruders and thus should be made available."
|
||||
assert "quality_type_0" in result, "This quality type was available for one of the extruders, and so there must be a group for it (even though it's unavailable)."
|
||||
assert not result["quality_type_0"].is_available, "This quality type was only available for one of the extruders and thus can't be activated."
|
||||
assert "quality_type_1" in result, "This quality type was available for one of the extruders, and so there must be a group for it (even though it's unavailable)."
|
||||
assert not result["quality_type_1"].is_available, "This quality type was only available for one of the extruders and thus can't be activated."
|
|
@ -13,13 +13,13 @@ material_node_added_test_data = [({"type": "Not a material"}, ["material_1", "ma
|
|||
({"type": "material", "base_file": "material_3"}, ["material_1", "material_2"]), # material_3 is on the "NOPE" list.
|
||||
({"type": "material", "base_file": "material_4", "definition": "machine_3"}, ["material_1", "material_2"]), # Wrong machine
|
||||
({"type": "material", "base_file": "material_4", "definition": "machine_1"}, ["material_1", "material_2"]), # No variant
|
||||
({"type": "material", "base_file": "material_4", "definition": "machine_1", "variant": "Variant Three"}, ["material_1", "material_2"]), # Wrong variant
|
||||
({"type": "material", "base_file": "material_4", "definition": "machine_1", "variant": "Variant One"}, ["material_1", "material_2", "material_4"])
|
||||
({"type": "material", "base_file": "material_4", "definition": "machine_1", "variant_name": "Variant Three"}, ["material_1", "material_2"]), # Wrong variant
|
||||
({"type": "material", "base_file": "material_4", "definition": "machine_1", "variant_name": "Variant One"}, ["material_1", "material_2", "material_4"])
|
||||
]
|
||||
|
||||
material_node_update_test_data = [({"type": "material", "base_file": "material_1", "definition": "machine_1", "variant": "Variant One"}, ["material_1"], ["material_2"]),
|
||||
({"type": "material", "base_file": "material_1", "definition": "fdmprinter", "variant": "Variant One"}, [], ["material_2", "material_1"]), # Too generic
|
||||
({"type": "material", "base_file": "material_1", "definition": "machine_2", "variant": "Variant One"}, [], ["material_2", "material_1"]) # Wrong definition
|
||||
material_node_update_test_data = [({"type": "material", "base_file": "material_1", "definition": "machine_1", "variant_name": "Variant One"}, ["material_1"], ["material_2"]),
|
||||
({"type": "material", "base_file": "material_1", "definition": "fdmprinter", "variant_name": "Variant One"}, [], ["material_2", "material_1"]), # Too generic
|
||||
({"type": "material", "base_file": "material_1", "definition": "machine_2", "variant_name": "Variant One"}, [], ["material_2", "material_1"]) # Wrong definition
|
||||
]
|
||||
|
||||
metadata_dict = {}
|
||||
|
|
|
@ -56,7 +56,7 @@ def test_createMachine(application, container_registry, definition_container, gl
|
|||
quality_container, intent_container, quality_changes_container):
|
||||
variant_manager = MagicMock(name = "Variant Manager")
|
||||
quality_manager = MagicMock(name = "Quality Manager")
|
||||
global_variant_node = MagicMock( name = "global variant node")
|
||||
global_variant_node = MagicMock(name = "global variant node")
|
||||
global_variant_node.container = global_variant
|
||||
|
||||
variant_manager.getDefaultVariantNode = MagicMock(return_value = global_variant_node)
|
||||
|
@ -98,7 +98,7 @@ def test_createExtruderStack(application, definition_container, global_variant,
|
|||
application.empty_quality_container = quality_container
|
||||
application.empty_intent_container = intent_container
|
||||
application.empty_quality_changes_container = quality_changes_container
|
||||
with patch("cura.CuraApplication.CuraApplication.getInstance", MagicMock(return_value=application)):
|
||||
with patch("cura.CuraApplication.CuraApplication.getInstance", MagicMock(return_value = application)):
|
||||
extruder_stack = CuraStackBuilder.createExtruderStack("Whatever", definition_container, "meh", 0, global_variant, material_instance_container, quality_container)
|
||||
assert extruder_stack.variant == global_variant
|
||||
assert extruder_stack.material == material_instance_container
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue