mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-15 10:47:49 -06:00
Merge branch 'master' of github.com:Ultimaker/Cura
This commit is contained in:
commit
51dee95c8f
6 changed files with 310 additions and 124 deletions
|
@ -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
132
cura/QualityManager.py
Normal 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]
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue