Merge pull request #4618 from Ultimaker/CURA-5834_fix_material_model_update

CURA-5834 Fix material model update
This commit is contained in:
Remco Burema 2018-10-23 14:54:34 +02:00 committed by GitHub
commit 3dab627670
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 23 deletions

View file

@ -365,7 +365,7 @@ class MaterialManager(QObject):
nozzle_name = None nozzle_name = None
if extruder_stack.variant.getId() != "empty_variant": if extruder_stack.variant.getId() != "empty_variant":
nozzle_name = extruder_stack.variant.getName() nozzle_name = extruder_stack.variant.getName()
diameter = extruder_stack.approximateMaterialDiameter diameter = extruder_stack.getApproximateMaterialDiameter()
# Fetch the available materials (ContainerNode) for the current active machine and extruder setup. # Fetch the available materials (ContainerNode) for the current active machine and extruder setup.
return self.getAvailableMaterials(machine.definition, nozzle_name, buildplate_name, diameter) return self.getAvailableMaterials(machine.definition, nozzle_name, buildplate_name, diameter)
@ -478,12 +478,22 @@ class MaterialManager(QObject):
buildplate_name = global_stack.getBuildplateName() buildplate_name = global_stack.getBuildplateName()
machine_definition = global_stack.definition machine_definition = global_stack.definition
if extruder_definition is None:
extruder_definition = global_stack.extruders[position].definition
if extruder_definition and parseBool(global_stack.getMetaDataEntry("has_materials", False)): # The extruder-compatible material diameter in the extruder definition may not be the correct value because
# At this point the extruder_definition is not None # the user can change it in the definition_changes container.
material_diameter = extruder_definition.getProperty("material_diameter", "value") if extruder_definition is None:
extruder_stack_or_definition = global_stack.extruders[position]
is_extruder_stack = True
else:
extruder_stack_or_definition = extruder_definition
is_extruder_stack = False
if extruder_stack_or_definition and parseBool(global_stack.getMetaDataEntry("has_materials", False)):
if is_extruder_stack:
material_diameter = extruder_stack_or_definition.getCompatibleMaterialDiameter()
else:
material_diameter = extruder_stack_or_definition.getProperty("material_diameter", "value")
if isinstance(material_diameter, SettingFunction): if isinstance(material_diameter, SettingFunction):
material_diameter = material_diameter(global_stack) material_diameter = material_diameter(global_stack)
approximate_material_diameter = str(round(material_diameter)) approximate_material_diameter = str(round(material_diameter))

View file

@ -64,9 +64,11 @@ class BaseMaterialsModel(ListModel):
if self._extruder_stack is not None: if self._extruder_stack is not None:
self._extruder_stack.pyqtContainersChanged.disconnect(self._update) self._extruder_stack.pyqtContainersChanged.disconnect(self._update)
self._extruder_stack.approximateMaterialDiameterChanged.disconnect(self._update)
self._extruder_stack = global_stack.extruders.get(str(self._extruder_position)) self._extruder_stack = global_stack.extruders.get(str(self._extruder_position))
if self._extruder_stack is not None: if self._extruder_stack is not None:
self._extruder_stack.pyqtContainersChanged.connect(self._update) self._extruder_stack.pyqtContainersChanged.connect(self._update)
self._extruder_stack.approximateMaterialDiameterChanged.connect(self._update)
# Force update the model when the extruder stack changes # Force update the model when the extruder stack changes
self._update() self._update()

View file

@ -129,7 +129,7 @@ class CuraStackBuilder:
# get material container for extruders # get material container for extruders
material_container = application.empty_material_container material_container = application.empty_material_container
material_node = material_manager.getDefaultMaterial(global_stack, extruder_position, extruder_variant_name, material_node = material_manager.getDefaultMaterial(global_stack, str(extruder_position), extruder_variant_name,
extruder_definition = extruder_definition) extruder_definition = extruder_definition)
if material_node and material_node.getContainer(): if material_node and material_node.getContainer():
material_container = material_node.getContainer() material_container = material_node.getContainer()

View file

@ -65,16 +65,33 @@ class ExtruderStack(CuraContainerStack):
def getLoadingPriority(cls) -> int: def getLoadingPriority(cls) -> int:
return 3 return 3
compatibleMaterialDiameterChanged = pyqtSignal()
## Return the filament diameter that the machine requires. ## Return the filament diameter that the machine requires.
# #
# If the machine has no requirement for the diameter, -1 is returned. # If the machine has no requirement for the diameter, -1 is returned.
# \return The filament diameter for the printer # \return The filament diameter for the printer
@property def getCompatibleMaterialDiameter(self) -> float:
def materialDiameter(self) -> float:
context = PropertyEvaluationContext(self) context = PropertyEvaluationContext(self)
context.context["evaluate_from_container_index"] = _ContainerIndexes.Variant context.context["evaluate_from_container_index"] = _ContainerIndexes.Variant
return self.getProperty("material_diameter", "value", context = context) return float(self.getProperty("material_diameter", "value", context = context))
def setCompatibleMaterialDiameter(self, value: float) -> None:
old_approximate_diameter = self.getApproximateMaterialDiameter()
if self.getCompatibleMaterialDiameter() != value:
self.definitionChanges.setProperty("material_diameter", "value", value)
self.compatibleMaterialDiameterChanged.emit()
# Emit approximate diameter changed signal if needed
if old_approximate_diameter != self.getApproximateMaterialDiameter():
self.approximateMaterialDiameterChanged.emit()
compatibleMaterialDiameter = pyqtProperty(float, fset = setCompatibleMaterialDiameter,
fget = getCompatibleMaterialDiameter,
notify = compatibleMaterialDiameterChanged)
approximateMaterialDiameterChanged = pyqtSignal()
## Return the approximate filament diameter that the machine requires. ## Return the approximate filament diameter that the machine requires.
# #
@ -84,9 +101,11 @@ class ExtruderStack(CuraContainerStack):
# If the machine has no requirement for the diameter, -1 is returned. # If the machine has no requirement for the diameter, -1 is returned.
# #
# \return The approximate filament diameter for the printer # \return The approximate filament diameter for the printer
@pyqtProperty(float) def getApproximateMaterialDiameter(self) -> float:
def approximateMaterialDiameter(self) -> float: return round(self.getCompatibleMaterialDiameter())
return round(float(self.materialDiameter))
approximateMaterialDiameter = pyqtProperty(float, fget = getApproximateMaterialDiameter,
notify = approximateMaterialDiameterChanged)
## Overridden from ContainerStack ## Overridden from ContainerStack
# #

View file

@ -1279,11 +1279,7 @@ class MachineManager(QObject):
if extruder.variant.getId() != empty_variant_container.getId(): if extruder.variant.getId() != empty_variant_container.getId():
current_nozzle_name = extruder.variant.getMetaDataEntry("name") current_nozzle_name = extruder.variant.getMetaDataEntry("name")
from UM.Settings.Interfaces import PropertyEvaluationContext material_diameter = extruder.getCompatibleMaterialDiameter()
from cura.Settings.CuraContainerStack import _ContainerIndexes
context = PropertyEvaluationContext(extruder)
context.context["evaluate_from_container_index"] = _ContainerIndexes.DefinitionChanges
material_diameter = extruder.getProperty("material_diameter", "value", context)
candidate_materials = self._material_manager.getAvailableMaterials( candidate_materials = self._material_manager.getAvailableMaterials(
self._global_container_stack.definition, self._global_container_stack.definition,
current_nozzle_name, current_nozzle_name,
@ -1418,7 +1414,7 @@ class MachineManager(QObject):
position = str(position) position = str(position)
extruder_stack = self._global_container_stack.extruders[position] extruder_stack = self._global_container_stack.extruders[position]
nozzle_name = extruder_stack.variant.getName() nozzle_name = extruder_stack.variant.getName()
material_diameter = extruder_stack.approximateMaterialDiameter material_diameter = extruder_stack.getApproximateMaterialDiameter()
material_node = self._material_manager.getMaterialNode(machine_definition_id, nozzle_name, buildplate_name, material_node = self._material_manager.getMaterialNode(machine_definition_id, nozzle_name, buildplate_name,
material_diameter, root_material_id) material_diameter, root_material_id)
self.setMaterial(position, material_node) self.setMaterial(position, material_node)

View file

@ -926,7 +926,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
build_plate_id = global_stack.variant.getId() build_plate_id = global_stack.variant.getId()
# get material diameter of this extruder # get material diameter of this extruder
machine_material_diameter = extruder_stack.materialDiameter machine_material_diameter = extruder_stack.getCompatibleMaterialDiameter()
material_node = material_manager.getMaterialNode(global_stack.definition.getId(), material_node = material_manager.getMaterialNode(global_stack.definition.getId(),
extruder_stack.variant.getName(), extruder_stack.variant.getName(),
build_plate_id, build_plate_id,

View file

@ -408,6 +408,10 @@ Cura.MachineAction
manager.updateMaterialForDiameter(settingsTabs.currentIndex - 1); manager.updateMaterialForDiameter(settingsTabs.currentIndex - 1);
} }
} }
function setValueFunction(value)
{
Cura.MachineManager.activeStack.compatibleMaterialDiameter = value
}
property bool isExtruderSetting: true property bool isExtruderSetting: true
} }
@ -564,6 +568,7 @@ Cura.MachineAction
property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false : forceUpdateOnChange property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false : forceUpdateOnChange
property string _label: (typeof(label) === 'undefined') ? "" : label property string _label: (typeof(label) === 'undefined') ? "" : label
property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
property var _setValueFunction: (typeof(setValueFunction) === 'undefined') ? undefined : setValueFunction
UM.SettingPropertyProvider UM.SettingPropertyProvider
{ {
@ -616,14 +621,32 @@ Cura.MachineAction
{ {
if (propertyProvider && text != propertyProvider.properties.value) if (propertyProvider && text != propertyProvider.properties.value)
{ {
propertyProvider.setPropertyValue("value", text); // For some properties like the extruder-compatible material diameter, they need to
// trigger many updates, such as the available materials, the current material may
// need to be switched, etc. Although setting the diameter can be done directly via
// the provider, all the updates that need to be triggered then need to depend on
// the metadata update, a signal that can be fired way too often. The update functions
// can have if-checks to filter out the irrelevant updates, but still it incurs unnecessary
// overhead.
// The ExtruderStack class has a dedicated function for this call "setCompatibleMaterialDiameter()",
// and it triggers the diameter update signals only when it is needed. Here it is optionally
// choose to use setCompatibleMaterialDiameter() or other more specific functions that
// are available.
if (_setValueFunction !== undefined)
{
_setValueFunction(text)
}
else
{
propertyProvider.setPropertyValue("value", text)
}
if(_forceUpdateOnChange) if(_forceUpdateOnChange)
{ {
manager.forceUpdate(); manager.forceUpdate()
} }
if(_afterOnEditingFinished) if(_afterOnEditingFinished)
{ {
_afterOnEditingFinished(); _afterOnEditingFinished()
} }
} }
} }