Merge branch 'master' of github.com:Ultimaker/Cura

This commit is contained in:
Jaime van Kessel 2016-09-21 16:37:39 +02:00
commit 51dee95c8f
6 changed files with 310 additions and 124 deletions

View file

@ -95,6 +95,11 @@ class BuildVolume(SceneNode):
self._change_timer.setSingleShot(True) self._change_timer.setSingleShot(True)
self._change_timer.timeout.connect(self._onChangeTimerFinished) self._change_timer.timeout.connect(self._onChangeTimerFinished)
self._build_volume_message = Message(catalog.i18nc("@info:status",
"The build volume height has been reduced due to the value of the"
" \"Print Sequence\" setting to prevent the gantry from colliding"
" with printed models."))
def _onSceneChanged(self, source): def _onSceneChanged(self, source):
self._change_timer.start() self._change_timer.start()
@ -252,13 +257,6 @@ class BuildVolume(SceneNode):
def getBoundingBox(self): def getBoundingBox(self):
return self._volume_aabb return self._volume_aabb
def _buildVolumeMessage(self):
Message(catalog.i18nc(
"@info:status",
"The build volume height has been reduced due to the value of the"
" \"Print Sequence\" setting to prevent the gantry from colliding"
" with printed models.")).show()
def getRaftThickness(self): def getRaftThickness(self):
return self._raft_thickness return self._raft_thickness
@ -299,9 +297,12 @@ class BuildVolume(SceneNode):
if self._global_container_stack.getProperty("print_sequence", "value") == "one_at_a_time" and self._number_of_objects > 1: if self._global_container_stack.getProperty("print_sequence", "value") == "one_at_a_time" and self._number_of_objects > 1:
self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height) self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height)
if self._height < machine_height: if self._height < machine_height:
self._buildVolumeMessage() self._build_volume_message.show()
else:
self._build_volume_message.hide()
else: else:
self._height = self._global_container_stack.getProperty("machine_height", "value") self._height = self._global_container_stack.getProperty("machine_height", "value")
self._build_volume_message.hide()
self._depth = self._global_container_stack.getProperty("machine_depth", "value") self._depth = self._global_container_stack.getProperty("machine_depth", "value")
self._updateDisallowedAreas() self._updateDisallowedAreas()
@ -319,9 +320,12 @@ class BuildVolume(SceneNode):
if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and self._number_of_objects > 1: if Application.getInstance().getGlobalContainerStack().getProperty("print_sequence", "value") == "one_at_a_time" and self._number_of_objects > 1:
self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height) self._height = min(self._global_container_stack.getProperty("gantry_height", "value"), machine_height)
if self._height < machine_height: if self._height < machine_height:
self._buildVolumeMessage() self._build_volume_message.show()
else:
self._build_volume_message.hide()
else: else:
self._height = self._global_container_stack.getProperty("machine_height", "value") self._height = self._global_container_stack.getProperty("machine_height", "value")
self._build_volume_message.hide()
rebuild_me = True rebuild_me = True
if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings or setting_key == "print_sequence" or setting_key in self._ooze_shield_settings: if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings or setting_key == "print_sequence" or setting_key in self._ooze_shield_settings:

132
cura/QualityManager.py Normal file
View file

@ -0,0 +1,132 @@
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
import UM.Application
import cura.Settings.ExtruderManager
import UM.Settings.ContainerRegistry
# This collects a lot of quality and quality changes related code which was split between ContainerManager
# and the MachineManager and really needs to usable from both.
class QualityManager:
## Get the singleton instance for this class.
@classmethod
def getInstance(cls):
# Note: Explicit use of class name to prevent issues with inheritance.
if QualityManager.__instance is None:
QualityManager.__instance = cls()
return QualityManager.__instance
__instance = None
## Find a quality by name for a specific machine definition and materials.
#
# \param quality_name
# \param machine_definition (Optional) \type{ContainerInstance} If nothing is
# specified then the currently selected machine definition is used.
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
# the current set of selected materials is used.
# \return the matching quality containers \type{List[ContainerInstance]}
def findQualityByName(self, quality_name, machine_definition=None, material_containers=None):
criteria = {"type": "quality", "name": quality_name}
return self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
## Find a quality changes container by name.
#
# \param quality_changes_name \type{str} the name of the quality changes container.
# \param machine_definition (Optional) \type{ContainerInstance} If nothing is
# specified then the currently selected machine definition is used.
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
# the current set of selected materials is used.
# \return the matching quality changes containers \type{List[ContainerInstance]}
def findQualityChangesByName(self, quality_changes_name, machine_definition=None, material_containers=None):
criteria = {"type": "quality_changes", "name": quality_changes_name}
return self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
## Find a quality container by quality type.
#
# \param quality_type \type{str} the name of the quality type to search for.
# \param machine_definition (Optional) \type{ContainerInstance} If nothing is
# specified then the currently selected machine definition is used.
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
# the current set of selected materials is used.
# \return the matching quality containers \type{List[ContainerInstance]}
def findQualityByQualityType(self, quality_type, machine_definition=None, material_containers=None):
criteria = {"type": "quality", "quality_type": quality_type}
return self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
def _getFilteredContainers(self, **kwargs):
return self._getFilteredContainersForStack(None, None **kwargs)
def _getFilteredContainersForStack(self, machine_definition=None, material_containers=None, **kwargs):
# Fill in any default values.
if machine_definition is None:
machine_definition = UM.Application.getInstance().getGlobalContainerStack().getBottom()
quality_definition = machine_definition.getMetaDataEntry("quality_definition")
if quality_definition is not None:
machine_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=quality_definition)[0]
machine_definition = self.getParentMachineDefinition(machine_definition)
if material_containers is None:
active_stacks = cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
material_containers = [stack.findContainer(type="material") for stack in active_stacks]
criteria = kwargs
filter_by_material = False
if machine_definition.getMetaDataEntry("has_machine_quality"):
definition_id = machine_definition.getMetaDataEntry("quality_definition", machine_definition.getId())
criteria["definition"] = definition_id
filter_by_material = machine_definition.getMetaDataEntry("has_materials")
# Stick the material IDs in a set
if material_containers is None:
filter_by_material = False
else:
material_ids = set()
for material_instance in material_containers:
material_ids.add(material_instance.getId())
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
result = []
for container in containers:
# If the machine specifies we should filter by material, exclude containers that do not match any active material.
if filter_by_material and container.getMetaDataEntry("material") not in material_ids:
continue
result.append(container)
return result
## Get the parent machine definition of a machine definition.
#
# \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or
# an extruder definition.
# \return \type{DefinitionContainer} the parent machine definition. If the given machine
# definition doesn't have a parent then it is simply returned.
def getParentMachineDefinition(self, machine_definition):
container_registry = UM.Settings.ContainerRegistry.getInstance()
machine_entry = machine_definition.getMetaDataEntry("machine")
if machine_entry is None:
# We have a normal (whole) machine defintion
quality_definition = machine_definition.getMetaDataEntry("quality_definition")
if quality_definition is not None:
parent_machine_definition = container_registry.findDefinitionContainers(id=quality_definition)[0]
return self.getParentMachineDefinition(parent_machine_definition)
else:
return machine_definition
else:
# This looks like an extruder. Find the rest of the machine.
whole_machine = container_registry.findDefinitionContainers(id=machine_entry)[0]
parent_machine = self.getParentMachineDefinition(whole_machine)
if whole_machine is parent_machine:
# This extruder already belongs to a 'parent' machine def.
return machine_definition
else:
# Look up the corresponding extruder definition in the parent machine definition.
extruder_position = machine_definition.getMetaDataEntry("position")
parent_extruder_id = parent_machine.getMetaDataEntry("machine_extruder_trains")[extruder_position]
return container_registry.findDefinitionContainers(id=parent_extruder_id)[0]

View file

@ -15,6 +15,7 @@ import UM.MimeTypeDatabase
import UM.Logger import UM.Logger
import cura.Settings import cura.Settings
from cura.QualityManager import QualityManager
from UM.MimeTypeDatabase import MimeTypeNotFoundError from UM.MimeTypeDatabase import MimeTypeNotFoundError
@ -468,7 +469,7 @@ class ContainerManager(QObject):
UM.Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId()) UM.Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
continue continue
new_changes = self._createQualityChanges(quality_container, unique_name, stack.getId()) new_changes = self._createQualityChanges(quality_container, unique_name, stack.getId(), UM.Application.getInstance().getGlobalContainerStack())
self._performMerge(new_changes, user_container) self._performMerge(new_changes, user_container)
self._container_registry.addContainer(new_changes) self._container_registry.addContainer(new_changes)
@ -566,33 +567,80 @@ class ContainerManager(QObject):
global_stack = UM.Application.getInstance().getGlobalContainerStack() global_stack = UM.Application.getInstance().getGlobalContainerStack()
if not global_stack or not quality_name: if not global_stack or not quality_name:
return "" return ""
machine_definition = global_stack.getBottom()
active_stacks = cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
material_containers = [stack.findContainer(type="material") for stack in active_stacks]
result = self._duplicateQualityOrQualityChangesForMachineType(quality_name, base_name,
QualityManager.getInstance().getParentMachineDefinition(machine_definition),
material_containers)
return result[0].getName() if result else ""
## Duplicate a quality or quality changes profile specific to a machine type
#
# \param quality_name \type{str} the name of the quality or quality changes container to duplicate.
# \param base_name \type{str} the desired name for the new container.
# \param machine_definition \type{DefinitionContainer}
# \param material_instances \type{List[InstanceContainer]}
# \return \type{str} the name of the newly created container.
def _duplicateQualityOrQualityChangesForMachineType(self, quality_name, base_name, machine_definition, material_instances):
UM.Logger.log("d", "Attempting to duplicate the quality %s", quality_name) UM.Logger.log("d", "Attempting to duplicate the quality %s", quality_name)
containers = self._container_registry.findInstanceContainers(name = quality_name)
if not containers: # Try Quality
containers = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances)
if containers:
container = containers[0]
if base_name is None:
base_name = quality_name
return self._duplicateQualityForMachineType(container, base_name, machine_definition)
# Try quality changes.
containers = QualityManager.getInstance().findQualityChangesByName(quality_name, machine_definition, material_instances)
if containers:
container = containers[0]
if base_name is None:
base_name = quality_name
return self._duplicateQualityChangesForMachineType(container, base_name, machine_definition)
else:
UM.Logger.log("d", "Unable to duplicate the quality %s, because it doesn't exist.", quality_name) UM.Logger.log("d", "Unable to duplicate the quality %s, because it doesn't exist.", quality_name)
return "" return ""
# Duplicate a quality profile
def _duplicateQualityForMachineType(self, quality_container, base_name, machine_definition):
if base_name is None: if base_name is None:
base_name = quality_name base_name = quality_container.getName()
new_name = self._container_registry.uniqueName(base_name) new_name = self._container_registry.uniqueName(base_name)
container_type = containers[0].getMetaDataEntry("type") new_change_instances = []
if container_type == "quality":
for container in self._getFilteredContainers(name = quality_name, type = "quality"):
for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
new_changes = self._createQualityChanges(container, new_name, stack.getId())
self._container_registry.addContainer(new_changes)
elif container_type == "quality_changes":
for container in self._getFilteredContainers(name = quality_name, type = "quality_changes"):
stack_id = container.getMetaDataEntry("extruder", global_stack.getId())
new_container = container.duplicate(self._createUniqueId(stack_id, new_name), new_name)
self._container_registry.addContainer(new_container)
else:
UM.Logger.log("w", "Unable to duplicate profile. It has the wrong type.")
return ""
return new_name # Handle the global stack first.
new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, None)
new_change_instances.append(new_changes)
self._container_registry.addContainer(new_changes)
# Handle the extruders if present.
extruders = machine_definition.getMetaDataEntry("machine_extruder_trains")
if extruders:
for key in extruders:
value = extruders[key]
new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, value)
new_change_instances.append(new_changes)
self._container_registry.addContainer(new_changes)
return new_change_instances
# Duplicate a quality changes container
def _duplicateQualityChangesForMachineType(self, quality_changes_container, base_name, machine_definition):
new_change_instances = []
for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_container.getName(),
machine_definition, None):
new_unique_id = self._createUniqueId(container.getId(), base_name)
new_container = container.duplicate(new_unique_id, base_name)
new_change_instances.append(new_container)
self._container_registry.addContainer(new_container)
return new_change_instances
@pyqtSlot(str, result = str) @pyqtSlot(str, result = str)
def duplicateMaterial(self, material_id): def duplicateMaterial(self, material_id):
@ -677,39 +725,13 @@ class ContainerManager(QObject):
name_filter = "{0} ({1})".format(mime_type.comment, suffix_list) name_filter = "{0} ({1})".format(mime_type.comment, suffix_list)
self._container_name_filters[name_filter] = entry self._container_name_filters[name_filter] = entry
## Return a generator that iterates over a set of containers that are filtered by machine and material when needed. ## Get containers filtered by machine type and material if required.
# #
# \param kwargs Initial search criteria that the containers need to match. # \param kwargs Initial search criteria that the containers need to match.
# #
# \return A generator that iterates over the list of containers matching the search criteria. # \return A list of containers matching the search criteria.
def _getFilteredContainers(self, **kwargs): def _getFilteredContainers(self, **kwargs):
global_stack = UM.Application.getInstance().getGlobalContainerStack() return QualityManager.getInstance()._getFilteredContainers(**kwargs)
if not global_stack:
return False
criteria = kwargs
filter_by_material = False
if global_stack.getMetaDataEntry("has_machine_quality"):
definition = global_stack.getBottom()
definition_id = definition.getMetaDataEntry("quality_definition", definition.getId())
criteria["definition"] = definition_id
filter_by_material = global_stack.getMetaDataEntry("has_materials")
material_ids = []
if filter_by_material:
for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
material_ids.append(stack.findContainer(type = "material").getId())
containers = self._container_registry.findInstanceContainers(**criteria)
for container in containers:
# If the machine specifies we should filter by material, exclude containers that do not match any active material.
if filter_by_material and container.getMetaDataEntry("material") not in material_ids:
continue
yield container
## Creates a unique ID for a container by prefixing the name with the stack ID. ## Creates a unique ID for a container by prefixing the name with the stack ID.
# #
@ -731,34 +753,26 @@ class ContainerManager(QObject):
# #
# \param quality_container The quality container to create a changes container for. # \param quality_container The quality container to create a changes container for.
# \param new_name The name of the new quality_changes container. # \param new_name The name of the new quality_changes container.
# \param stack_id The ID of the container stack the new container "belongs to". It is used primarily to ensure a unique ID. # \param machine_definition The machine definition this quality changes container is specific to.
# \param extruder_id
# #
# \return A new quality_changes container with the specified container as base. # \return A new quality_changes container with the specified container as base.
def _createQualityChanges(self, quality_container, new_name, stack_id): def _createQualityChanges(self, quality_container, new_name, machine_definition, extruder_id):
global_stack = UM.Application.getInstance().getGlobalContainerStack() base_id = machine_definition.getId() if extruder_id is None else extruder_id
assert global_stack is not None
# Create a new quality_changes container for the quality. # Create a new quality_changes container for the quality.
quality_changes = UM.Settings.InstanceContainer(self._createUniqueId(stack_id, new_name)) quality_changes = UM.Settings.InstanceContainer(self._createUniqueId(base_id, new_name))
quality_changes.setName(new_name) quality_changes.setName(new_name)
quality_changes.addMetaDataEntry("type", "quality_changes") quality_changes.addMetaDataEntry("type", "quality_changes")
quality_changes.addMetaDataEntry("quality", quality_container.getMetaDataEntry("quality_type")) quality_changes.addMetaDataEntry("quality_type", quality_container.getMetaDataEntry("quality_type"))
# If we are creating a container for an extruder, ensure we add that to the container # If we are creating a container for an extruder, ensure we add that to the container
if stack_id != global_stack.getId(): if extruder_id is not None:
quality_changes.addMetaDataEntry("extruder", stack_id) quality_changes.addMetaDataEntry("extruder", extruder_id)
# If the machine specifies qualities should be filtered, ensure we match the current criteria. # If the machine specifies qualities should be filtered, ensure we match the current criteria.
if not global_stack.getMetaDataEntry("has_machine_quality"): if not machine_definition.getMetaDataEntry("has_machine_quality"):
quality_changes.setDefinition(self._container_registry.findContainers(id = "fdmprinter")[0]) quality_changes.setDefinition(self._container_registry.findContainers(id = "fdmprinter")[0])
else: else:
definition = global_stack.getBottom() quality_changes.setDefinition(QualityManager.getInstance().getParentMachineDefinition(machine_definition))
definition_id = definition.getMetaDataEntry("quality_definition", definition.getId())
definition = self._container_registry.findContainers(id=definition_id)[0]
quality_changes.setDefinition(definition)
if global_stack.getMetaDataEntry("has_materials"):
material = quality_container.getMetaDataEntry("material")
quality_changes.addMetaDataEntry("material", material)
return quality_changes return quality_changes

View file

@ -12,6 +12,7 @@ from UM.Settings.SettingRelation import RelationType
import UM.Settings import UM.Settings
from cura.QualityManager import QualityManager
from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutputDevice import PrinterOutputDevice
from . import ExtruderManager from . import ExtruderManager
@ -535,10 +536,10 @@ class MachineManager(QObject):
if not old_material: if not old_material:
Logger.log("w", "While trying to set the active material, no material was found to replace it.") Logger.log("w", "While trying to set the active material, no material was found to replace it.")
return return
if (old_quality_changes.getId() == "empty_quality_changes" or #Don't want the empty one.
old_quality_changes.getMetaDataEntry("material") != material_id): # The quality change is based off a different material; the quality change is probably a custom quality.
if old_quality_changes.getId() == "empty_quality_changes":
old_quality_changes = None old_quality_changes = None
self.blurSettings.emit() self.blurSettings.emit()
old_material.nameChanged.disconnect(self._onMaterialNameChanged) old_material.nameChanged.disconnect(self._onMaterialNameChanged)
@ -596,22 +597,26 @@ class MachineManager(QObject):
Logger.log("d", "Attempting to change the active quality to %s", quality_id) Logger.log("d", "Attempting to change the active quality to %s", quality_id)
self.blurSettings.emit() self.blurSettings.emit()
quality_container = None
quality_changes_container = self._empty_quality_changes_container quality_changes_container = self._empty_quality_changes_container
# Quality profile come in two flavours: type=quality and type=quality_changes
# If we found a quality_changes profile then look up its parent quality profile.
container_type = containers[0].getMetaDataEntry("type") container_type = containers[0].getMetaDataEntry("type")
# Get quality container and optionally the quality_changes container. # Get quality container and optionally the quality_changes container.
if container_type == "quality": if container_type == "quality":
quality_container = containers[0] quality_container = containers[0]
elif container_type == "quality_changes": elif container_type == "quality_changes":
quality_changes_container = containers[0] quality_changes_container = containers[0]
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers( # Find a suitable quality container to match this quality changes container.
quality_type = quality_changes_container.getMetaDataEntry("quality")) containers = QualityManager.getInstance().findQualityByQualityType(quality_changes_container.getMetaDataEntry("quality_type"))
if not containers: if not containers:
Logger.log("e", "Could not find quality %s for changes %s, not changing quality", quality_changes_container.getMetaDataEntry("quality"), quality_changes_container.getId()) Logger.log("e", "Could not find quality %s for changes %s, not changing quality", quality_changes_container.getMetaDataEntry("quality"), quality_changes_container.getId())
return return
quality_container = containers[0] quality_container = containers[0]
else: else:
Logger.log("e", "Tried to set quality to a container that is not of the right type") Logger.log("e", "Tried to set quality to a container that is not of the right type")
return return
@ -620,25 +625,33 @@ class MachineManager(QObject):
if not quality_type: if not quality_type:
quality_type = quality_changes_container.getName() quality_type = quality_changes_container.getName()
# Find suitable quality containers (by quality_type) for each stack and swap out the container. # Find and swap in the quality changes containers for the global stack and each extruder stack.
stacks = list(ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()) stacks = list(ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks())
name_changed_connect_stacks = [] # Connect these stacks to the name changed callback name_changed_connect_stacks = [] # Connect these stacks to the name changed callback
for stack in stacks: for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
extruder_id = stack.getId() if stack != self._global_container_stack else None if stack != self._global_container_stack:
# Must be an extruder stack. Use the ID of the extruders as specified by the machine definition.
criteria = { "quality_type": quality_type, "extruder": extruder_id } extruder_id = QualityManager.getInstance().getParentMachineDefinition(stack.getBottom()).getId()
else:
extruder_id = None
criteria = { "quality_type": quality_type, "type": "quality", "extruder": extruder_id }
# Filter candidate quality containers by the current material in the stack.
material = stack.findContainer(type = "material") material = stack.findContainer(type = "material")
if material and material is not self._empty_material_container: if material and material is not self._empty_material_container:
criteria["material"] = material.getId() criteria["material"] = material.getId()
# Apply a filter when machines have their own specific quality profiles.
if self._global_container_stack.getMetaDataEntry("has_machine_quality"): if self._global_container_stack.getMetaDataEntry("has_machine_quality"):
criteria["definition"] = self.activeQualityDefinitionId criteria["definition"] = self.activeQualityDefinitionId
else: else:
criteria["definition"] = "fdmprinter" criteria["definition"] = "fdmprinter"
# Find the new quality container.
stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
if not stack_quality: if not stack_quality:
# Search again, except this time drop any extruder requirement. We should now get
# the same quality container as the one needed for the global stack.
criteria.pop("extruder") criteria.pop("extruder")
stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria) stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
if not stack_quality: if not stack_quality:
@ -648,28 +661,21 @@ class MachineManager(QObject):
else: else:
stack_quality = stack_quality[0] stack_quality = stack_quality[0]
# Find the new quality changes if one has been specified.
if quality_changes_container != self._empty_quality_changes_container: if quality_changes_container != self._empty_quality_changes_container:
stack_quality_changes = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(name = quality_changes_container.getName(), extruder = extruder_id)[0] changes = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(
type="quality_changes",
quality_type=stack_quality.getMetaDataEntry("quality_type"),
name = quality_changes_container.getName(), extruder = extruder_id)
stack_quality_changes = changes[0]
else: else:
# This is case of quality container and the no-op quality changes container.
stack_quality_changes = self._empty_quality_changes_container stack_quality_changes = self._empty_quality_changes_container
old_quality = stack.findContainer(type = "quality")
if old_quality:
old_quality.nameChanged.disconnect(self._onQualityNameChanged)
else:
Logger.log("w", "Could not find old quality while changing active quality.")
old_changes = stack.findContainer(type = "quality_changes")
if old_changes:
old_changes.nameChanged.disconnect(self._onQualityNameChanged)
else:
Logger.log("w", "Could not find old quality_changes while changing active quality.")
stack.replaceContainer(stack.getContainerIndex(old_quality), stack_quality, postpone_emit = True)
stack.replaceContainer(stack.getContainerIndex(old_changes), stack_quality_changes, postpone_emit = True)
name_changed_connect_stacks.append(stack_quality) name_changed_connect_stacks.append(stack_quality)
name_changed_connect_stacks.append(stack_quality_changes) name_changed_connect_stacks.append(stack_quality_changes)
self._replaceQualityOrQualityChangesInStack(stack, stack_quality, postpone_emit = True)
self._replaceQualityOrQualityChangesInStack(stack, stack_quality_changes, postpone_emit = True)
# Send emits that are postponed in replaceContainer. # Send emits that are postponed in replaceContainer.
# Here the stacks are finished replacing and every value can be resolved based on the current state. # Here the stacks are finished replacing and every value can be resolved based on the current state.
@ -680,6 +686,25 @@ class MachineManager(QObject):
stack.nameChanged.connect(self._onQualityNameChanged) stack.nameChanged.connect(self._onQualityNameChanged)
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1: if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
self._askUserToKeepOrClearCurrentSettings()
self.activeQualityChanged.emit()
def _replaceQualityOrQualityChangesInStack(self, stack, container, postpone_emit = False):
# Disconnect the signal handling from the old container.
old_container = stack.findContainer(type=container.getMetaDataEntry("type"))
if old_container:
old_container.nameChanged.disconnect(self._onQualityNameChanged)
else:
Logger.log("w", "Could not find old "+ container.getMetaDataEntry("type") + " while changing active " + container.getMetaDataEntry("type") + ".")
# Swap in the new container into the stack.
stack.replaceContainer(stack.getContainerIndex(old_container), container, postpone_emit = postpone_emit)
# Attach the needed signal handling.
container.nameChanged.connect(self._onQualityNameChanged)
def _askUserToKeepOrClearCurrentSettings(self):
# Ask the user if the user profile should be cleared or not (discarding the current settings) # Ask the user if the user profile should be cleared or not (discarding the current settings)
# In Simple Mode we assume the user always wants to keep the (limited) current settings # In Simple Mode we assume the user always wants to keep the (limited) current settings
details = catalog.i18nc("@label", "You made changes to the following setting(s):") details = catalog.i18nc("@label", "You made changes to the following setting(s):")
@ -687,11 +712,14 @@ class MachineManager(QObject):
for setting in user_settings: for setting in user_settings:
details = details + "\n " + setting.definition.label details = details + "\n " + setting.definition.label
Application.getInstance().messageBox(catalog.i18nc("@window:title", "Switched profiles"), catalog.i18nc("@label", "Do you want to transfer your changed settings to this profile?"), Application.getInstance().messageBox(catalog.i18nc("@window:title", "Switched profiles"),
catalog.i18nc("@label", "If you transfer your settings they will override settings in the profile."), details, catalog.i18nc("@label",
buttons = QMessageBox.Yes + QMessageBox.No, icon = QMessageBox.Question, callback = self._keepUserSettingsDialogCallback) "Do you want to transfer your changed settings to this profile?"),
catalog.i18nc("@label",
self.activeQualityChanged.emit() "If you transfer your settings they will override settings in the profile."),
details,
buttons=QMessageBox.Yes + QMessageBox.No, icon=QMessageBox.Question,
callback=self._keepUserSettingsDialogCallback)
def _keepUserSettingsDialogCallback(self, button): def _keepUserSettingsDialogCallback(self, button):
if button == QMessageBox.Yes: if button == QMessageBox.Yes:
@ -746,10 +774,7 @@ class MachineManager(QObject):
# \param definition (DefinitionContainer) machine definition # \param definition (DefinitionContainer) machine definition
# \returns DefinitionID (string) if found, empty string otherwise # \returns DefinitionID (string) if found, empty string otherwise
def getQualityDefinitionId(self, definition): def getQualityDefinitionId(self, definition):
definition_id = definition.getMetaDataEntry("quality_definition") return QualityManager.getInstance().getParentMachineDefinition(definition).getId()
if not definition_id:
definition_id = definition.getId()
return definition_id
## Get the Variant ID to use to select quality profiles for the currently active variant ## Get the Variant ID to use to select quality profiles for the currently active variant
# \returns VariantID (string) if found, empty string otherwise # \returns VariantID (string) if found, empty string otherwise

View file

@ -38,11 +38,11 @@ Menu
id: customProfileInstantiator id: customProfileInstantiator
model: UM.InstanceContainersModel model: UM.InstanceContainersModel
{ {
filter: menu.getFilter({ filter: ({
"type": "quality_changes", "type": "quality_changes",
"extruder": null, "extruder": null,
"definition": Cura.MachineManager.filterQualityByMachine ? Cura.MachineManager.activeQualityDefinitionId : "fdmprinter" "definition": Cura.MachineManager.filterQualityByMachine ? Cura.MachineManager.activeQualityDefinitionId : "fdmprinter"
}); })
onModelReset: customSeparator.visible = rowCount() > 0 onModelReset: customSeparator.visible = rowCount() > 0
} }

View file

@ -17,22 +17,33 @@ UM.ManagementPage
model: UM.InstanceContainersModel model: UM.InstanceContainersModel
{ {
filter: filterList:
{ {
var result = { "type": "quality*", "extruder": null }; var qualityFilter = { "type": "quality", "extruder": null };
if(Cura.MachineManager.filterQualityByMachine) if(Cura.MachineManager.filterQualityByMachine)
{ {
result.definition = Cura.MachineManager.activeQualityDefinitionId; qualityFilter.definition = Cura.MachineManager.activeQualityDefinitionId;
if(Cura.MachineManager.hasMaterials) if(Cura.MachineManager.hasMaterials)
{ {
result.material = Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId]; qualityFilter.material = Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId];
} }
} }
else else
{ {
result.definition = "fdmprinter" qualityFilter.definition = "fdmprinter";
} }
return result
var qualityChangeFilter = { "type": "quality_changes", "extruder": null };
if(Cura.MachineManager.filterQualityByMachine)
{
qualityChangeFilter.definition = Cura.MachineManager.activeQualityDefinitionId;
}
else
{
qualityChangeFilter.definition = "fdmprinter";
}
return [qualityFilter, qualityChangeFilter];
} }
} }