mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-06 05:23:58 -06:00
Merge branch 'feature_material_inheritance' of github.com:Ultimaker/Cura
This commit is contained in:
commit
fbbbdb61e3
2 changed files with 77 additions and 2 deletions
|
@ -19,6 +19,7 @@ from UM.i18n import i18nCatalog
|
|||
catalog = i18nCatalog("cura")
|
||||
|
||||
import time
|
||||
import os
|
||||
|
||||
class MachineManager(QObject):
|
||||
def __init__(self, parent = None):
|
||||
|
@ -502,7 +503,7 @@ class MachineManager(QObject):
|
|||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
|
||||
Logger.log("d", "Attempting to change the active material to %s", material_id)
|
||||
old_variant = self._active_container_stack.findContainer({"type": "variant"})
|
||||
old_material = self._active_container_stack.findContainer({"type": "material"})
|
||||
old_quality = self._active_container_stack.findContainer({"type": "quality"})
|
||||
|
@ -535,6 +536,7 @@ class MachineManager(QObject):
|
|||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
|
||||
if not containers or not self._active_container_stack:
|
||||
return
|
||||
Logger.log("d", "Attempting to change the active variant to %s", variant_id)
|
||||
old_variant = self._active_container_stack.findContainer({"type": "variant"})
|
||||
old_material = self._active_container_stack.findContainer({"type": "material"})
|
||||
if old_variant:
|
||||
|
@ -554,6 +556,9 @@ class MachineManager(QObject):
|
|||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id)
|
||||
if not containers or not self._global_container_stack:
|
||||
return
|
||||
|
||||
Logger.log("d", "Attempting to change the active quality to %s", quality_id)
|
||||
|
||||
self.blurSettings.emit()
|
||||
quality_container = None
|
||||
quality_changes_container = self._empty_quality_changes_container
|
||||
|
@ -829,7 +834,22 @@ class MachineManager(QObject):
|
|||
return containers[0]
|
||||
|
||||
if "material" in search_criteria:
|
||||
# If a quality for this specific material cannot be found, try finding qualities for a generic version of the material
|
||||
# First check if we can solve our material not found problem by checking if we can find quality containers
|
||||
# that are assigned to the parents of this material profile.
|
||||
try:
|
||||
inherited_files = material_container.getInheritedFiles()
|
||||
if inherited_files:
|
||||
for inherited_file in inherited_files:
|
||||
# Extract the ID from the path we used to load the file.
|
||||
search_criteria["material"] = os.path.basename(inherited_file).split(".")[0]
|
||||
containers = container_registry.findInstanceContainers(**search_criteria)
|
||||
if containers:
|
||||
return containers[0]
|
||||
except AttributeError: # Material_container does not support inheritance.
|
||||
pass
|
||||
|
||||
# We still weren't able to find a quality for this specific material.
|
||||
# Try to find qualities for a generic version of the material.
|
||||
material_search_criteria = { "type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic" }
|
||||
if definition.getMetaDataEntry("has_machine_quality"):
|
||||
if material_container:
|
||||
|
|
|
@ -7,8 +7,10 @@ import io
|
|||
import xml.etree.ElementTree as ET
|
||||
import uuid
|
||||
|
||||
from UM.Resources import Resources
|
||||
from UM.Logger import Logger
|
||||
from UM.Util import parseBool
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
||||
import UM.Dictionary
|
||||
|
||||
|
@ -18,6 +20,7 @@ import UM.Settings
|
|||
class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
||||
def __init__(self, container_id, *args, **kwargs):
|
||||
super().__init__(container_id, *args, **kwargs)
|
||||
self._inherited_files = []
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def duplicate(self, new_id, new_name = None):
|
||||
|
@ -48,6 +51,9 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
result.setMetaDataEntry("base_file", result.id)
|
||||
return result
|
||||
|
||||
def getInheritedFiles(self):
|
||||
return self._inherited_files
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def setReadOnly(self, read_only):
|
||||
super().setReadOnly(read_only)
|
||||
|
@ -246,6 +252,50 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
|
||||
return stream.getvalue()
|
||||
|
||||
# Recursively resolve loading inherited files
|
||||
def _resolveInheritance(self, file_name):
|
||||
xml = self._loadFile(file_name)
|
||||
|
||||
inherits = xml.find("./um:inherits", self.__namespaces)
|
||||
if inherits is not None:
|
||||
inherited = self._resolveInheritance(inherits.text)
|
||||
xml = self._mergeXML(inherited, xml)
|
||||
|
||||
return xml
|
||||
|
||||
def _loadFile(self, file_name):
|
||||
path = Resources.getPath(CuraApplication.getInstance().ResourceTypes.MaterialInstanceContainer, file_name + ".xml.fdm_material")
|
||||
|
||||
with open(path, encoding="utf-8") as f:
|
||||
contents = f.read()
|
||||
|
||||
self._inherited_files.append(path)
|
||||
return ET.fromstring(contents)
|
||||
|
||||
def _mergeXML(self, first, second):
|
||||
result = copy.deepcopy(first)
|
||||
self._combineElement(result, second)
|
||||
return result
|
||||
|
||||
# Recursively merges XML elements. Updates either the text or children if another element is found in first.
|
||||
# If it does not exist, copies it from second.
|
||||
def _combineElement(self, first, second):
|
||||
# Create a mapping from tag name to element.
|
||||
mapping = {el.tag: el for el in first}
|
||||
for el in second:
|
||||
if len(el): # Check if element has children.
|
||||
try:
|
||||
self._combineElement(mapping[el.tag], el) # Multiple elements, handle those.
|
||||
except KeyError:
|
||||
mapping[el.tag] = el
|
||||
first.append(el)
|
||||
else:
|
||||
try:
|
||||
mapping[el.tag].text = el.text
|
||||
except KeyError: # Not in the mapping, so simply add it
|
||||
mapping[el.tag] = el
|
||||
first.append(el)
|
||||
|
||||
## Overridden from InstanceContainer
|
||||
def deserialize(self, serialized):
|
||||
data = ET.fromstring(serialized)
|
||||
|
@ -255,6 +305,11 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
|
||||
# TODO: Add material verfication
|
||||
self.addMetaDataEntry("status", "unknown")
|
||||
#for inherit in data.findall("./um:inherits", self.__namespaces):
|
||||
inherits = data.find("./um:inherits", self.__namespaces)
|
||||
if inherits is not None:
|
||||
inherited = self._resolveInheritance(inherits.text)
|
||||
data = self._mergeXML(inherited, data)
|
||||
|
||||
metadata = data.iterfind("./um:metadata/*", self.__namespaces)
|
||||
for entry in metadata:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue