WIP: Fix material duplication and metadata update

This commit is contained in:
Lipu Fei 2018-02-16 12:12:43 +01:00
parent 188c0343cf
commit a5afaab467
4 changed files with 23 additions and 32 deletions

View file

@ -69,8 +69,7 @@ class MaterialManager(QObject):
# Find all materials and put them in a matrix for quick search. # Find all materials and put them in a matrix for quick search.
material_metadata_list = self._container_registry.findContainersMetadata(type = "material") material_metadata_list = self._container_registry.findContainersMetadata(type = "material")
self._material_group_map = OrderedDict() self._material_group_map = dict()
self._diameter_machine_variant_material_map = {}
# Map #1 # Map #1
# root_material_id -> MaterialGroup # root_material_id -> MaterialGroup
@ -155,6 +154,7 @@ class MaterialManager(QObject):
# Map #4 # Map #4
# "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer # "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer
# Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer # Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer
self._diameter_machine_variant_material_map = dict()
for material_metadata in material_metadata_list: for material_metadata in material_metadata_list:
# We don't store empty material in the lookup tables # We don't store empty material in the lookup tables
if material_metadata["id"] == "empty_material": if material_metadata["id"] == "empty_material":

View file

@ -42,8 +42,10 @@ class ContainerManager(QObject):
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
self._application = Application.getInstance()
self._container_registry = ContainerRegistry.getInstance() self._container_registry = ContainerRegistry.getInstance()
self._machine_manager = Application.getInstance().getMachineManager() self._machine_manager = self._application.getMachineManager()
self._material_manager = self._application._material_manager
self._container_name_filters = {} self._container_name_filters = {}
## Create a duplicate of the specified container ## Create a duplicate of the specified container
@ -211,18 +213,15 @@ class ContainerManager(QObject):
# \param entry_value The new value of the entry. # \param entry_value The new value of the entry.
# #
# \return True if successful, False if not. # \return True if successful, False if not.
@pyqtSlot(str, str, str, result = bool) # TODO: This is ONLY used by MaterialView for material containers. Maybe refactor this.
def setContainerMetaDataEntry(self, container_id, entry_name, entry_value): @pyqtSlot("QVariant", str, str)
if self._container_registry.isReadOnly(container_id): def setContainerMetaDataEntry(self, container_node, entry_name, entry_value):
Logger.log("w", "Cannot set metadata of read-only container %s.", container_id) root_material_id = container_node.metadata["base_file"]
if self._container_registry.isReadOnly(root_material_id):
Logger.log("w", "Cannot set metadata of read-only container %s.", root_material_id)
return False return False
containers = self._container_registry.findContainers(id = container_id) #We need the complete container, since we need to know whether the container is read-only or not. material_group = self._material_manager.getMaterialGroup(root_material_id)
if not containers:
Logger.log("w", "Could not set metadata of container %s because it was not found.", container_id)
return False
container = containers[0]
entries = entry_name.split("/") entries = entry_name.split("/")
entry_name = entries.pop() entry_name = entries.pop()
@ -230,7 +229,7 @@ class ContainerManager(QObject):
sub_item_changed = False sub_item_changed = False
if entries: if entries:
root_name = entries.pop(0) root_name = entries.pop(0)
root = container.getMetaDataEntry(root_name) root = material_group.root_material_node.metadata.get(root_name)
item = root item = root
for _ in range(len(entries)): for _ in range(len(entries)):
@ -243,12 +242,11 @@ class ContainerManager(QObject):
entry_name = root_name entry_name = root_name
entry_value = root entry_value = root
container = material_group.root_material_node.getContainer()
container.setMetaDataEntry(entry_name, entry_value) container.setMetaDataEntry(entry_name, entry_value)
if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed. if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed.
container.metaDataChanged.emit(container) container.metaDataChanged.emit(container)
return True
## Set a setting property of the specified container. ## Set a setting property of the specified container.
# #
# This will set the specified property of the specified setting of the container # This will set the specified property of the specified setting of the container
@ -768,10 +766,7 @@ class ContainerManager(QObject):
def duplicateMaterial(self, material_node): def duplicateMaterial(self, material_node):
root_material_id = material_node.metadata["base_file"] root_material_id = material_node.metadata["base_file"]
from cura.CuraApplication import CuraApplication material_group = self._material_manager.getMaterialGroup(root_material_id)
material_manager = CuraApplication.getInstance()._material_manager
material_group = material_manager.getMaterialGroup(root_material_id)
if not material_group: if not material_group:
Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id) Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id)
return "" return ""
@ -867,10 +862,7 @@ class ContainerManager(QObject):
def getLinkedMaterials(self, material_node): def getLinkedMaterials(self, material_node):
guid = material_node.metadata["GUID"] guid = material_node.metadata["GUID"]
from cura.CuraApplication import CuraApplication material_group_list = self._material_manager.getMaterialGroupListByGUID(guid)
material_manager = CuraApplication.getInstance()._material_manager
material_group_list = material_manager.getMaterialGroupListByGUID(guid)
linked_material_names = [] linked_material_names = []
if material_group_list: if material_group_list:
@ -883,9 +875,7 @@ class ContainerManager(QObject):
@pyqtSlot("QVariant") @pyqtSlot("QVariant")
def unlinkMaterial(self, material_node): def unlinkMaterial(self, material_node):
# Get the material group # Get the material group
from cura.CuraApplication import CuraApplication material_group = self._material_manager.getMaterialGroup(material_node.metadata["base_file"])
material_manager = CuraApplication.getInstance()._material_manager
material_group = material_manager.getMaterialGroup(material_node.metadata["base_file"])
# Generate a new GUID # Generate a new GUID
new_guid = str(uuid.uuid4()) new_guid = str(uuid.uuid4())

View file

@ -48,14 +48,15 @@ class XmlMaterialProfile(InstanceContainer):
## Overridden from InstanceContainer ## Overridden from InstanceContainer
# set the meta data for all machine / variant combinations # set the meta data for all machine / variant combinations
def setMetaDataEntry(self, key, value, is_first_call = True): def setMetaDataEntry(self, key, value, apply_to_all = True):
registry = ContainerRegistry.getInstance() registry = ContainerRegistry.getInstance()
if registry.isReadOnly(self.getId()): if registry.isReadOnly(self.getId()):
return return
# Prevent recursion # Prevent recursion
if is_first_call: if not apply_to_all:
super().setMetaDataEntry(key, value) super().setMetaDataEntry(key, value)
return
# Get the MaterialGroup # Get the MaterialGroup
material_manager = CuraApplication.getInstance()._material_manager material_manager = CuraApplication.getInstance()._material_manager
@ -64,12 +65,12 @@ class XmlMaterialProfile(InstanceContainer):
# Update the root material container # Update the root material container
root_material_container = material_group.root_material_node.getContainer() root_material_container = material_group.root_material_node.getContainer()
root_material_container.setMetaDataEntry(key, value, is_first_call = False) root_material_container.setMetaDataEntry(key, value, apply_to_all = False)
# Update all containers derived from it # Update all containers derived from it
for node in material_group.derived_material_node_list: for node in material_group.derived_material_node_list:
container = node.getContainer() container = node.getContainer()
container.setMetaDataEntry(key, value, is_first_call = False) container.setMetaDataEntry(key, value, apply_to_all = False)
## Overridden from InstanceContainer, similar to setMetaDataEntry. ## Overridden from InstanceContainer, similar to setMetaDataEntry.
# without this function the setName would only set the name of the specific nozzle / material / machine combination container # without this function the setName would only set the name of the specific nozzle / material / machine combination container

View file

@ -417,7 +417,7 @@ TabView
// Tiny convenience function to check if a value really changed before trying to set it. // Tiny convenience function to check if a value really changed before trying to set it.
function setMetaDataEntry(entry_name, old_value, new_value) { function setMetaDataEntry(entry_name, old_value, new_value) {
if (old_value != new_value) { if (old_value != new_value) {
Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value) Cura.ContainerManager.setContainerMetaDataEntry(base.currentMaterialNode, entry_name, new_value)
// make sure the UI properties are updated as well since we don't re-fetch the entire model here // make sure the UI properties are updated as well since we don't re-fetch the entire model here
// When the entry_name is something like properties/diameter, we take the last part of the entry_name // When the entry_name is something like properties/diameter, we take the last part of the entry_name
var list = entry_name.split("/") var list = entry_name.split("/")