Merge pull request #6479 from Ultimaker/CURA-6840_intent_profile_visibility

Cura 6840 intent profile visibility
This commit is contained in:
Lipu Fei 2019-10-07 08:18:28 +02:00 committed by GitHub
commit 1981a7c65b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 93 additions and 109 deletions

View File

@ -1,18 +1,16 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, List, Dict, Any
from typing import Optional, Dict, Any, Set, List
from PyQt5.QtCore import Qt, QObject, pyqtProperty, pyqtSignal
import cura.CuraApplication
from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.SettingFunction import SettingFunction
from cura.Machines.ContainerTree import ContainerTree
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.IntentManager import IntentManager
import cura.CuraApplication
from cura.Machines.MaterialNode import MaterialNode
from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
from cura.Machines.QualityGroup import QualityGroup
class IntentModel(ListModel):
@ -65,54 +63,23 @@ class IntentModel(ListModel):
return
quality_groups = ContainerTree.getInstance().getCurrentQualityGroups()
container_tree = ContainerTree.getInstance()
machine_node = container_tree.machines[global_stack.definition.getId()]
material_nodes = self._getActiveMaterials()
# We can't just look at the active extruder, since it is possible for only one extruder to have an intent
# and the other extruders have no intent (eg, default). It is not possible for one extruder to have intent A and
# the other to have B.
# So we will use the first extruder that we find that has an intent that is not default as the "active" extruder
layer_heights_added = [] # type: List[float]
active_extruder = None
for extruder in global_stack.extruderList:
if not extruder.isEnabled:
continue
if extruder.intent.getMetaDataEntry("intent_category", "default") == "default":
if active_extruder is None:
active_extruder = extruder # If there is no extruder found and the intent is default, use that.
else: # We found an intent, use that extruder as "active"
active_extruder = extruder
if not active_extruder:
return
active_variant_name = active_extruder.variant.getMetaDataEntry("name")
active_variant_node = machine_node.variants[active_variant_name]
active_material_node = active_variant_node.materials[active_extruder.material.getMetaDataEntry("base_file")]
layer_heights_added = []
for quality_id, quality_node in active_material_node.qualities.items():
if quality_node.quality_type not in quality_groups: # Don't add the empty quality type (or anything else that would crash, defensively).
continue
quality_group = quality_groups[quality_node.quality_type]
layer_height = self._fetchLayerHeight(quality_group)
for intent_id, intent_node in quality_node.intents.items():
if intent_node.intent_category != self._intent_category:
continue
layer_heights_added.append(layer_height)
new_items.append({"name": quality_group.name,
"quality_type": quality_group.quality_type,
"layer_height": layer_height,
"available": quality_group.is_available,
"intent_category": self._intent_category
})
for material_node in material_nodes:
intents = self._getIntentsForMaterial(material_node, quality_groups)
for intent in intents:
if intent["layer_height"] not in layer_heights_added:
new_items.append(intent)
layer_heights_added.append(intent["layer_height"])
# Now that we added all intents that we found something for, ensure that we set add ticks (and layer_heights)
# for all groups that we don't have anything for (and set it to not available)
for quality_tuple, quality_group in quality_groups.items():
# Add the intents that are of the correct category
if quality_tuple[0] != self._intent_category:
layer_height = self._fetchLayerHeight(quality_group)
layer_height = fetchLayerHeight(quality_group)
if layer_height not in layer_heights_added:
new_items.append({"name": "Unavailable",
"quality_type": "",
@ -124,35 +91,43 @@ class IntentModel(ListModel):
new_items = sorted(new_items, key=lambda x: x["layer_height"])
self.setItems(new_items)
#TODO: Copied this from QualityProfilesDropdownMenuModel for the moment. This code duplication should be fixed.
def _fetchLayerHeight(self, quality_group) -> float:
global_stack = cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMachine
if not self._layer_height_unit:
unit = global_stack.definition.getProperty("layer_height", "unit")
if not unit:
unit = ""
self._layer_height_unit = unit
## Get the active materials for all extruders. No duplicates will be returned
def _getActiveMaterials(self) -> Set["MaterialNode"]:
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
if global_stack is None:
return set()
default_layer_height = global_stack.definition.getProperty("layer_height", "value")
container_tree = ContainerTree.getInstance()
machine_node = container_tree.machines[global_stack.definition.getId()]
nodes = set() # type: Set[MaterialNode]
# Get layer_height from the quality profile for the GlobalStack
if quality_group.node_for_global is None:
return float(default_layer_height)
container = quality_group.node_for_global.container
for extruder in global_stack.extruderList:
active_variant_name = extruder.variant.getMetaDataEntry("name")
active_variant_node = machine_node.variants[active_variant_name]
active_material_node = active_variant_node.materials[extruder.material.getMetaDataEntry("base_file")]
nodes.add(active_material_node)
layer_height = default_layer_height
if container and container.hasProperty("layer_height", "value"):
layer_height = container.getProperty("layer_height", "value")
else:
# Look for layer_height in the GlobalStack from material -> definition
container = global_stack.definition
if container and container.hasProperty("layer_height", "value"):
layer_height = container.getProperty("layer_height", "value")
return nodes
if isinstance(layer_height, SettingFunction):
layer_height = layer_height(global_stack)
def _getIntentsForMaterial(self, active_material_node: "MaterialNode", quality_groups: Dict[str, "QualityGroup"]) -> List[Dict[str, Any]]:
extruder_intents = [] # type: List[Dict[str, Any]]
return float(layer_height)
for quality_id, quality_node in active_material_node.qualities.items():
if quality_node.quality_type not in quality_groups: # Don't add the empty quality type (or anything else that would crash, defensively).
continue
quality_group = quality_groups[quality_node.quality_type]
layer_height = fetchLayerHeight(quality_group)
for intent_id, intent_node in quality_node.intents.items():
if intent_node.intent_category != self._intent_category:
continue
extruder_intents.append({"name": quality_group.name,
"quality_type": quality_group.quality_type,
"layer_height": layer_height,
"available": quality_group.is_available,
"intent_category": self._intent_category
})
return extruder_intents
def __repr__(self):
return str(self.items)

View File

@ -0,0 +1,37 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import TYPE_CHECKING
from UM.Settings.SettingFunction import SettingFunction
if TYPE_CHECKING:
from cura.Machines.QualityGroup import QualityGroup
layer_height_unit = ""
def fetchLayerHeight(quality_group: "QualityGroup") -> float:
from cura.CuraApplication import CuraApplication
global_stack = CuraApplication.getInstance().getMachineManager().activeMachine
default_layer_height = global_stack.definition.getProperty("layer_height", "value")
# Get layer_height from the quality profile for the GlobalStack
if quality_group.node_for_global is None:
return float(default_layer_height)
container = quality_group.node_for_global.container
layer_height = default_layer_height
if container and container.hasProperty("layer_height", "value"):
layer_height = container.getProperty("layer_height", "value")
else:
# Look for layer_height in the GlobalStack from material -> definition
container = global_stack.definition
if container and container.hasProperty("layer_height", "value"):
layer_height = container.getProperty("layer_height", "value")
if isinstance(layer_height, SettingFunction):
layer_height = layer_height(global_stack)
return float(layer_height)

View File

@ -2,17 +2,12 @@
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import Qt, QTimer
from typing import TYPE_CHECKING
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
from UM.Settings.SettingFunction import SettingFunction
import cura.CuraApplication # Imported this way to prevent circular dependencies.
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
from cura.Machines.ContainerTree import ContainerTree
if TYPE_CHECKING:
from cura.Machines.QualityGroup import QualityGroup
from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
#
@ -76,6 +71,12 @@ class QualityProfilesDropDownMenuModel(ListModel):
Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
return
if not self._layer_height_unit:
unit = global_stack.definition.getProperty("layer_height", "unit")
if not unit:
unit = ""
self._layer_height_unit = unit
# Check for material compatibility
if not cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMaterialsCompatible():
Logger.log("d", "No active material compatibility, set quality profile model as empty.")
@ -86,7 +87,7 @@ class QualityProfilesDropDownMenuModel(ListModel):
item_list = []
for quality_group in quality_group_dict.values():
layer_height = self._fetchLayerHeight(quality_group)
layer_height = fetchLayerHeight(quality_group)
item = {"name": quality_group.name,
"quality_type": quality_group.quality_type,
@ -102,32 +103,3 @@ class QualityProfilesDropDownMenuModel(ListModel):
item_list = sorted(item_list, key = lambda x: x["layer_height"])
self.setItems(item_list)
def _fetchLayerHeight(self, quality_group: "QualityGroup") -> float:
global_stack = cura.CuraApplication.CuraApplication.getInstance().getMachineManager().activeMachine
if not self._layer_height_unit:
unit = global_stack.definition.getProperty("layer_height", "unit")
if not unit:
unit = ""
self._layer_height_unit = unit
default_layer_height = global_stack.definition.getProperty("layer_height", "value")
# Get layer_height from the quality profile for the GlobalStack
if quality_group.node_for_global is None:
return float(default_layer_height)
container = quality_group.node_for_global.container
layer_height = default_layer_height
if container and container.hasProperty("layer_height", "value"):
layer_height = container.getProperty("layer_height", "value")
else:
# Look for layer_height in the GlobalStack from material -> definition
container = global_stack.definition
if container and container.hasProperty("layer_height", "value"):
layer_height = container.getProperty("layer_height", "value")
if isinstance(layer_height, SettingFunction):
layer_height = layer_height(global_stack)
return float(layer_height)