WIP: Create MaterialManager

This commit is contained in:
Lipu Fei 2018-02-07 14:49:46 +01:00
parent 55bdc0c853
commit f0d9fba2f5
7 changed files with 504 additions and 130 deletions

View file

@ -53,7 +53,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.SettingFunction import SettingFunction
from cura.Settings.MachineNameValidator import MachineNameValidator
from cura.Settings.ProfilesModel import ProfilesModel
from cura.Settings.MaterialsModel import MaterialsModel
from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel
from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
from cura.Settings.UserProfilesModel import UserProfilesModel
@ -734,6 +734,10 @@ class CuraApplication(QtApplication):
container_registry = ContainerRegistry.getInstance()
self._variant_manager.initialize()
from cura.Machines.MaterialManager import MaterialManager
self._material_manager = MaterialManager(container_registry)
self._material_manager.initialize()
# Check if we should run as single instance or not
self._setUpSingleInstanceServer()
@ -914,6 +918,10 @@ class CuraApplication(QtApplication):
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
qmlRegisterSingletonType(ProfilesModel, "Cura", 1, 0, "ProfilesModel", ProfilesModel.createProfilesModel)
qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel")
qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel")
qmlRegisterType(QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel")
qmlRegisterType(UserProfilesModel, "Cura", 1, 0, "UserProfilesModel")

View file

@ -0,0 +1,277 @@
from typing import Optional
from PyQt5.Qt import QTimer, QObject, pyqtSignal
from UM.Logger import Logger
from UM.Settings import ContainerRegistry
from UM.Settings import InstanceContainer
from cura.Machines.ContainerNode import ContainerNode
class MaterialGroup:
__slots__ = ("name", "root_material_node", "derived_material_node_list")
def __init__(self, name: str):
self.name = name
self.root_material_node = None
self.derived_material_node_list = []
class MaterialNode(ContainerNode):
__slots__ = ("material_map", "children_map")
def __init__(self, metadata: Optional[dict] = None):
super().__init__(metadata = metadata)
self.material_map = {}
self.children_map = {}
class MaterialManager(QObject):
materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated.
def __init__(self, container_registry, parent = None):
super().__init__(parent)
self._container_registry = container_registry # type: ContainerRegistry
self._fallback_materials_map = dict() # material_type -> generic material metadata
self._material_group_map = dict() # root_material_id -> MaterialGroup
self._diameter_machine_variant_material_map = dict() # diameter -> dict(machine_definition_id -> MaterialNode)
# The machine definition ID for the non-machine-specific materials.
# This is used as the last fallback option if the given machine-specific material(s) cannot be found.
self._default_machine_definition_id = "fdmprinter"
self._update_timer = QTimer(self)
self._update_timer.setInterval(300)
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._updateTables)
self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
def initialize(self):
# Find all materials and put them in a matrix for quick search.
material_metadata_list = self._container_registry.findContainersMetadata(type = "material")
self._material_group_map = {}
self._diameter_machine_variant_material_map = {}
# Table #1
# root_material_id -> MaterialGroup
for material_metadata in material_metadata_list:
material_id = material_metadata["id"]
# We don't store empty material in the lookup tables
if material_id == "empty_material":
continue
root_material_id = material_metadata.get("base_file")
if root_material_id not in self._material_group_map:
self._material_group_map[root_material_id] = MaterialGroup(root_material_id)
group = self._material_group_map[root_material_id]
# We only add root materials here
if material_id == root_material_id:
group.root_material_node = MaterialNode(material_metadata)
else:
new_node = MaterialNode(material_metadata)
group.derived_material_node_list.append(new_node)
# Table #2
# Lookup table for material type -> fallback material metadata
grouped_by_type_dict = dict()
for root_material_id, material_node in self._material_group_map.items():
material_type = material_node.root_material_node.metadata["material"]
if material_type not in grouped_by_type_dict:
grouped_by_type_dict[material_type] = {"generic": None,
"others": []}
brand = material_node.root_material_node.metadata["brand"]
if brand.lower() == "generic":
grouped_by_type_dict[material_type] = material_node.root_material_node.metadata
self._fallback_materials_map = grouped_by_type_dict
# Table #3
# "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer
# Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer
for material_metadata in material_metadata_list:
# We don't store empty material in the lookup tables
if material_metadata["id"] == "empty_material":
continue
root_material_id = material_metadata["base_file"]
definition = material_metadata["definition"]
approximate_diameter = material_metadata["approximate_diameter"]
if approximate_diameter not in self._diameter_machine_variant_material_map:
self._diameter_machine_variant_material_map[approximate_diameter] = {}
machine_variant_material_map = self._diameter_machine_variant_material_map[approximate_diameter]
if definition not in machine_variant_material_map:
machine_variant_material_map[definition] = MaterialNode()
machine_node = machine_variant_material_map[definition]
variant_name = material_metadata.get("variant_name")
if not variant_name:
# if there is no variant, this material is for the machine, so put its metadata in the machine node.
machine_node.material_map[root_material_id] = MaterialNode(material_metadata)
else:
# this material is variant-specific, so we save it in a variant-specific node under the
# machine-specific node
if variant_name not in machine_node.children_map:
machine_node.children_map[variant_name] = MaterialNode()
variant_node = machine_node.children_map[variant_name]
if root_material_id not in variant_node.material_map:
variant_node.material_map[root_material_id] = MaterialNode(material_metadata)
else:
# Sanity check: make sure we don't have duplicated variant-specific materials for the same machine
raise RuntimeError("Found duplicate variant name [%s] for machine [%s] in material [%s]" %
(variant_name, definition, material_metadata["id"]))
self.materialsUpdated.emit()
def _updateTables(self):
self.initialize()
def _onContainerMetadataChanged(self, container):
self._onContainerChanged(container)
def _onContainerChanged(self, container):
container_type = container.getMetaDataEntry("type")
if container_type != "material":
return
# TODO: update the cache table
self._update_timer.start()
def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]:
return self._material_group_map.get(root_material_id)
def _test_metadata(self):
# print all metadata
import os
with open("c:/workspace/guid_map.txt", "w", encoding = "utf-8") as f:
for machine_id, node in self._guid_to_root_materials_map.items():
f.write((" - %s -> %s" % (machine_id, node.metadata["id"])) + os.linesep)
if False:
with open("c:/workspace/material_map.txt", "w", encoding = "utf-8") as f:
for machine_id in self._machine_variant_material_map:
f.write((" -> %s" % machine_id) + os.linesep)
test_cases = [{"machine": "ultimaker3", "variant": "AA 0.4", "material": "generic_pla", "diameter": 2.85},
{"machine": "ultimaker2_plus", "variant": None, "material": "generic_abs", "diameter": 2.85},
{"machine": "fdmprinter", "variant": None, "material": "generic_cpe", "diameter": 2.85},
{"machine": "fdmprinter", "variant": None, "material": "generic_abs_175", "diameter": 2.85},
{"machine": "fdmprinter", "variant": None, "material": "generic_nylon", "diameter": 1.75},
{"machine": "fdmprinter", "variant": None, "material": "generic_nylon_175", "diameter": 1.75},
]
for tc in test_cases:
result = self.getMaterialNode(
tc['machine'],
tc['variant'],
tc['diameter'],
tc['material'])
tc['result_id'] = result.getContainer().getId() if result else "None"
Logger.log("d", "!!!!!!!! MaterialManager test: %s", tc)
# test available materials
with open("c:/workspace/test.txt", "w", encoding="utf-8") as f:
for tc in test_cases:
result = self.getAvailableMaterials(tc['machine'],
tc['variant'],
tc['diameter'])
f.write("--- [%s] [%s] [%s]:" % (tc['machine'], tc['variant'], tc['diameter']) + "\n")
for r, md in result.items():
f.write(" - %s -> %s" % (r, md["id"]) + "\n")
#
# Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup.
#
def getAvailableMaterials(self, machine_definition_id: str, variant_name: Optional[str], diameter: float) -> dict:
# round the diameter to get the approximate diameter
rounded_diameter = str(round(diameter))
if rounded_diameter not in self._diameter_machine_variant_material_map:
Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s])", diameter, rounded_diameter)
return {}
# If there are variant materials, get the variant material
machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter]
machine_node = machine_variant_material_map.get(machine_definition_id)
variant_node = None
if machine_node is None:
machine_node = machine_variant_material_map.get(self._default_machine_definition_id)
if variant_name is not None and machine_node is not None:
variant_node = machine_node.getChildNode(variant_name)
# Fallback mechanism of finding materials:
# 1. variant-specific material
# 2. machine-specific material
# 3. generic material (for fdmprinter)
material_id_metadata_dict = {}
if variant_node is not None:
material_id_metadata_dict = {mid: node for mid, node in variant_node.material_map.items()}
# Fallback: machine-specific materials, including "fdmprinter"
if not material_id_metadata_dict:
if machine_node is not None:
material_id_metadata_dict = {mid: node for mid, node in machine_node.material_map.items()}
return material_id_metadata_dict
#
# Gets MaterialNode for the given extruder and machine with the given material name.
# Returns None if:
# 1. the given machine doesn't have materials;
# 2. cannot find any material InstanceContainers with the given settings.
#
def getMaterial(self, machine_definition_id: str, variant_name: Optional[str], diameter: float, root_material_id: str) -> Optional["InstanceContainer"]:
# round the diameter to get the approximate diameter
rounded_diameter = str(round(diameter))
if rounded_diameter not in self._diameter_machine_variant_material_map:
Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s]) for root material id [%s]",
diameter, rounded_diameter, root_material_id)
return None
# If there are variant materials, get the variant material
machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter]
machine_node = machine_variant_material_map.get(machine_definition_id)
variant_node = None
# Fallback for "fdmprinter" if the machine-specific materials cannot be found
if machine_node is None:
machine_node = machine_variant_material_map.get(self._default_machine_definition_id)
if machine_node is not None and variant_name is not None:
variant_node = machine_node.getChildNode(variant_name)
# Fallback mechanism of finding materials:
# 1. variant-specific material
# 2. machine-specific material
# 3. generic material (for fdmprinter)
material_node = None
if variant_node is not None:
if root_material_id in variant_node.material_map:
material_node = variant_node.material_map.get(root_material_id)
# Fallback: machine-specific materials, including "fdmprinter"
if material_node is None:
if machine_node is not None:
material_node = machine_node.material_map.get(root_material_id)
return material_node
#
# Used by QualityManager. Built-in quality profiles may be based on generic material IDs such as "generic_pla".
# For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use
# the generic material IDs to search for qualities.
#
# This function returns the generic root material ID for the given material type, where material types are "PLA",
# "ABS", etc.
#
def getFallbackMaterialForType(self, material_type: str) -> dict:
# For safety
if material_type not in self._fallback_materials_map:
raise RuntimeError("Material type [%s] is not in the fallback materials table." % material_type)
return self._fallback_materials_map[material_type]

View file

@ -766,22 +766,20 @@ class ContainerManager(QObject):
# \return \type{str} the id of the newly created container.
@pyqtSlot(str, result = str)
def duplicateMaterial(self, material_id: str) -> str:
original = self._container_registry.findContainersMetadata(id = material_id)
if not original:
assert material_id
from cura.CuraApplication import CuraApplication
material_manager = CuraApplication.getInstance()._material_manager
material_group = material_manager.getMaterialGroup(material_id)
if not material_group:
Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id)
return ""
original = original[0]
base_container_id = original.get("base_file")
base_container = self._container_registry.findContainers(id = base_container_id)
if not base_container:
Logger.log("d", "Unable to duplicate the material with id {material_id}, because base_file {base_container_id} doesn't exist.".format(material_id = material_id, base_container_id = base_container_id))
return ""
base_container = base_container[0]
#We'll copy all containers with the same base.
#This way the correct variant and machine still gets assigned when loading the copy of the material.
containers_to_copy = self._container_registry.findInstanceContainers(base_file = base_container_id)
base_container = material_group.root_material_node.getContainer()
containers_to_copy = []
for node in material_group.derived_material_node_list:
containers_to_copy.append(node.getContainer())
# Ensure all settings are saved.
Application.getInstance().saveSettings()
@ -802,9 +800,9 @@ class ContainerManager(QObject):
new_id = new_base_id
if container_to_copy.getMetaDataEntry("definition") != "fdmprinter":
new_id += "_" + container_to_copy.getMetaDataEntry("definition")
if container_to_copy.getMetaDataEntry("variant"):
variant = self._container_registry.findContainers(id = container_to_copy.getMetaDataEntry("variant"))[0]
new_id += "_" + variant.getName().replace(" ", "_")
if container_to_copy.getMetaDataEntry("variant_name"):
variant_name = container_to_copy.getMetaDataEntry("variant_name")
new_id += "_" + variant_name.replace(" ", "_")
if current_id == material_id:
clone_of_original = new_id
@ -826,13 +824,7 @@ class ContainerManager(QObject):
# check if the given material has a base file (i.e. was shipped by default)
base_file = self.getContainerMetaDataEntry(material_id, "base_file")
if base_file == "":
# there is no base file, so duplicate by ID
return self.duplicateMaterial(material_id)
else:
# there is a base file, so duplicate the original material
return self.duplicateMaterial(base_file)
return self.duplicateMaterial(base_file)
## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue
#

View file

@ -1237,6 +1237,14 @@ class MachineManager(QObject):
return self.getQualityVariantId(self._global_container_stack.definition, variant)
return ""
@pyqtProperty(str, notify = activeVariantChanged)
def activeQualityVariantName(self) -> str:
if self._active_container_stack:
variant = self._active_container_stack.variant
if variant.getId() != "empty_variant":
return variant.getName()
return ""
## Get the Variant ID to use to select quality profiles for variants of the specified definitions
# This is normally the id of the variant itself, but machines can specify a different definition
# to inherit qualities from, which has consequences for the variant to use as well

View file

@ -2,10 +2,189 @@
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Any, List
from PyQt5.QtCore import Qt
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerRegistry import ContainerRegistry #To listen for changes to the materials.
from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel #We're extending this class.
## A model that shows a list of currently valid materials.
def getAvailableMaterials():
from cura.CuraApplication import CuraApplication
machine_manager = CuraApplication.getInstance().getMachineManager()
extruder_manager = CuraApplication.getInstance().getExtruderManager()
material_manager = CuraApplication.getInstance()._material_manager
active_global_stack = machine_manager._global_container_stack
active_extruder_stack = extruder_manager.getActiveExtruderStack()
if active_global_stack is None or active_extruder_stack is None:
Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.",
active_global_stack, active_extruder_stack)
return
machine_definition_id = active_global_stack.definition.getId()
variant_name = None
if active_extruder_stack.variant.getId() != "empty_variant":
variant_name = active_extruder_stack.variant.getName()
diameter = active_extruder_stack.getProperty("material_diameter", "value")
# Fetch the available materials (ContainerNode) for the current active machine and extruder setup.
result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter)
return result_dict
class BaseMaterialsModel(ListModel):
RootMaterialIdRole = Qt.UserRole + 1
IdRole = Qt.UserRole + 2
NameRole = Qt.UserRole + 3
BrandRole = Qt.UserRole + 4
MaterialRole = Qt.UserRole + 5
ColorRole = Qt.UserRole + 6
ContainerNodeRole = Qt.UserRole + 6
def __init__(self, parent = None):
super().__init__(parent)
self.addRoleName(self.RootMaterialIdRole, "root_material_id")
self.addRoleName(self.IdRole, "id")
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.BrandRole, "brand")
self.addRoleName(self.MaterialRole, "material")
self.addRoleName(self.ColorRole, "color_name")
self.addRoleName(self.ContainerNodeRole, "container_node")
class GenericMaterialsModel(BaseMaterialsModel):
def __init__(self, parent = None):
super().__init__(parent)
from cura.CuraApplication import CuraApplication
machine_manager = CuraApplication.getInstance().getMachineManager()
extruder_manager = CuraApplication.getInstance().getExtruderManager()
material_manager = CuraApplication.getInstance()._material_manager
machine_manager.globalContainerChanged.connect(self._update)
extruder_manager.activeExtruderChanged.connect(self._update)
material_manager.materialsUpdated.connect(self._update)
def _update(self):
item_list = []
result_dict = getAvailableMaterials()
if result_dict is None:
self.setItems([])
return
for root_material_id, container_node in result_dict.items():
metadata = container_node.metadata
# Only add results for generic materials
if metadata["brand"].lower() != "generic":
continue
item = {"root_material_id": root_material_id,
"id": metadata["id"],
"name": metadata["name"],
"brand": metadata["brand"],
"material": metadata["material"],
"color_name": metadata["color_name"],
"container_node": container_node
}
item_list.append(item)
# Sort the item list by material name alphabetically
item_list = sorted(item_list, key = lambda d: d["name"])
self.setItems(item_list)
class MaterialsModelGroupedByType(ListModel):
NameRole = Qt.UserRole + 1
ColorsRole = Qt.UserRole + 2
def __init__(self, parent = None):
super().__init__(parent)
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.ColorsRole, "colors")
## Brand --> Material Type -> list of materials
class BrandMaterialsModel(ListModel):
NameRole = Qt.UserRole + 1
MaterialsRole = Qt.UserRole + 2
def __init__(self, parent = None):
super().__init__(parent)
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.MaterialsRole, "materials")
from cura.CuraApplication import CuraApplication
machine_manager = CuraApplication.getInstance().getMachineManager()
extruder_manager = CuraApplication.getInstance().getExtruderManager()
material_manager = CuraApplication.getInstance()._material_manager
machine_manager.globalContainerChanged.connect(self._update)
extruder_manager.activeExtruderChanged.connect(self._update)
material_manager.materialsUpdated.connect(self._update)
def _update(self):
brand_item_list = []
result_dict = getAvailableMaterials()
if result_dict is None:
self.setItems([])
return
brand_group_dict = {}
for root_material_id, container_node in result_dict.items():
metadata = container_node.metadata
brand = metadata["brand"]
# Only add results for generic materials
if brand.lower() == "generic":
continue
if brand not in brand_group_dict:
brand_group_dict[brand] = {}
material_type = metadata["material"]
if material_type not in brand_group_dict[brand]:
brand_group_dict[brand][material_type] = []
item = {"root_material_id": root_material_id,
"id": metadata["id"],
"name": metadata["name"],
"brand": metadata["brand"],
"material": metadata["material"],
"color_name": metadata["color_name"],
"container_node": container_node
}
brand_group_dict[brand][material_type].append(item)
for brand, material_dict in brand_group_dict.items():
brand_item = {"name": brand,
"materials": MaterialsModelGroupedByType(self)} # TODO
material_type_item_list = []
for material_type, material_list in material_dict.items():
material_type_item = {"name": material_type,
"colors": BaseMaterialsModel(self)}
material_type_item["colors"].clear()
material_type_item["colors"].setItems(material_list)
material_type_item_list.append(material_type_item)
brand_item["materials"].setItems(material_type_item_list)
brand_item_list.append(brand_item)
self.setItems(brand_item_list)
## A model that shows a list of currently valid materials. Used by management page.
class MaterialsModel(InstanceContainersModel):
def __init__(self, parent = None):
super().__init__(parent)

View file

@ -1,8 +1,8 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick 2.8
import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
@ -29,16 +29,6 @@ Menu
return true;
}
UM.SettingPropertyProvider
{
id: materialDiameterProvider
containerStackId: Cura.ExtruderManager.activeExtruderStackId
key: "material_diameter"
watchedProperties: [ "value" ]
storeIndex: 5
}
MenuItem
{
id: automaticMaterial
@ -83,12 +73,16 @@ Menu
exclusiveGroup: group
onTriggered:
{
const container_id = model.id;
// This workaround is done because of the application menus for materials and variants for multiextrusion printers.
// The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
Cura.MachineManager.setActiveMaterial(model.id);
Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
//Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
//Cura.MachineManager.setActiveMaterial(container_id);
//Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
Cura.MachineManager.setMaterial(activeExtruderIndex, model.container_node);
}
}
onObjectAdded: menu.insertItem(index, object)
@ -126,11 +120,12 @@ Menu
exclusiveGroup: group
onTriggered:
{
const container_id = model.id;
// This workaround is done because of the application menus for materials and variants for multiextrusion printers.
// The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
Cura.MachineManager.setActiveMaterial(model.id);
Cura.MachineManager.setActiveMaterial(container_id);
Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
}
}
@ -146,105 +141,20 @@ Menu
onObjectRemoved: menu.removeItem(object)
}
ListModel
Cura.GenericMaterialsModel
{
id: genericMaterialsModel
Component.onCompleted: populateMenuModels()
//Component.onCompleted: populateMenuModels()
}
ListModel
Cura.BrandMaterialsModel
{
id: brandModel
}
//: Model used to populate the brandModel
Cura.MaterialsModel
{
id: materialsModel
filter: materialFilter()
onModelReset: populateMenuModels()
onDataChanged: populateMenuModels()
}
ExclusiveGroup { id: group }
MenuSeparator { }
MenuItem { action: Cura.Actions.manageMaterials }
function materialFilter()
{
var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() };
if(Cura.MachineManager.filterMaterialsByMachine)
{
result.definition = Cura.MachineManager.activeQualityDefinitionId;
if(Cura.MachineManager.hasVariants)
{
result.variant = Cura.MachineManager.activeQualityVariantId;
}
}
else
{
result.definition = "fdmprinter";
result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
}
return result;
}
function populateMenuModels()
{
// Create a structure of unique brands and their material-types
genericMaterialsModel.clear()
brandModel.clear();
var items = materialsModel.items;
var materialsByBrand = {};
for (var i in items) {
var brandName = items[i]["metadata"]["brand"];
var materialName = items[i]["metadata"]["material"];
if (brandName == "Generic")
{
// Add to top section
var materialId = items[i].id;
genericMaterialsModel.append({
id: materialId,
name: items[i].name
});
}
else
{
// Add to per-brand, per-material menu
if (!materialsByBrand.hasOwnProperty(brandName))
{
materialsByBrand[brandName] = {};
}
if (!materialsByBrand[brandName].hasOwnProperty(materialName))
{
materialsByBrand[brandName][materialName] = [];
}
materialsByBrand[brandName][materialName].push({
id: items[i].id,
name: items[i].name
});
}
}
for (var brand in materialsByBrand)
{
var materialsByBrandModel = [];
var materials = materialsByBrand[brand];
for (var material in materials)
{
materialsByBrandModel.push({
name: material,
colors: materials[material]
})
}
brandModel.append({
name: brand,
materials: materialsByBrandModel
});
}
}
}

View file

@ -30,7 +30,7 @@ UM.ManagementPage
result.definition = Cura.MachineManager.activeQualityDefinitionId;
if(Cura.MachineManager.hasVariants)
{
result.variant = Cura.MachineManager.activeQualityVariantId;
result.variant_name = Cura.MachineManager.activeQualityVariantName;
}
}
else