mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-12 09:17:50 -06:00
CURA-4400 fixed merge conflicts
This commit is contained in:
commit
bad637eb14
121 changed files with 1157 additions and 936 deletions
|
@ -821,6 +821,7 @@ class BuildVolume(SceneNode):
|
||||||
offset_y = extruder.getProperty("machine_nozzle_offset_y", "value")
|
offset_y = extruder.getProperty("machine_nozzle_offset_y", "value")
|
||||||
if offset_y is None:
|
if offset_y is None:
|
||||||
offset_y = 0
|
offset_y = 0
|
||||||
|
offset_y = -offset_y #Y direction of g-code is the inverse of Y direction of Cura's scene space.
|
||||||
result[extruder_id] = []
|
result[extruder_id] = []
|
||||||
|
|
||||||
for polygon in machine_disallowed_polygons:
|
for polygon in machine_disallowed_polygons:
|
||||||
|
|
|
@ -57,10 +57,10 @@ from cura.Settings.MachineNameValidator import MachineNameValidator
|
||||||
|
|
||||||
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
|
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
|
||||||
from cura.Machines.Models.NozzleModel import NozzleModel
|
from cura.Machines.Models.NozzleModel import NozzleModel
|
||||||
from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel
|
from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
|
||||||
from cura.Machines.Models.CustomQualityProfilesModel import CustomQualityProfilesModel
|
from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
|
||||||
|
|
||||||
from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel
|
from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
|
||||||
|
|
||||||
from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel
|
from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel
|
||||||
from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
|
from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
|
||||||
|
@ -399,8 +399,8 @@ class CuraApplication(QtApplication):
|
||||||
|
|
||||||
self.getCuraSceneController().setActiveBuildPlate(0) # Initialize
|
self.getCuraSceneController().setActiveBuildPlate(0) # Initialize
|
||||||
|
|
||||||
self._quality_profile_model = None
|
self._quality_profile_drop_down_menu_model = None
|
||||||
self._custom_quality_profile_model = None
|
self._custom_quality_profile_drop_down_menu_model = None
|
||||||
|
|
||||||
CuraApplication.Created = True
|
CuraApplication.Created = True
|
||||||
|
|
||||||
|
@ -859,6 +859,7 @@ class CuraApplication(QtApplication):
|
||||||
def getVariantManager(self, *args):
|
def getVariantManager(self, *args):
|
||||||
return self._variant_manager
|
return self._variant_manager
|
||||||
|
|
||||||
|
@pyqtSlot(result = QObject)
|
||||||
def getMaterialManager(self, *args):
|
def getMaterialManager(self, *args):
|
||||||
return self._material_manager
|
return self._material_manager
|
||||||
|
|
||||||
|
@ -918,15 +919,15 @@ class CuraApplication(QtApplication):
|
||||||
def getPrintInformation(self):
|
def getPrintInformation(self):
|
||||||
return self._print_information
|
return self._print_information
|
||||||
|
|
||||||
def getQualityProfileModel(self, *args, **kwargs):
|
def getQualityProfilesDropDownMenuModel(self, *args, **kwargs):
|
||||||
if self._quality_profile_model is None:
|
if self._quality_profile_drop_down_menu_model is None:
|
||||||
self._quality_profile_model = QualityProfilesModel(self)
|
self._quality_profile_drop_down_menu_model = QualityProfilesDropDownMenuModel(self)
|
||||||
return self._quality_profile_model
|
return self._quality_profile_drop_down_menu_model
|
||||||
|
|
||||||
def getCustomQualityProfilesModel(self, *args, **kwargs):
|
def getCustomQualityProfilesDropDownMenuModel(self, *args, **kwargs):
|
||||||
if self._custom_quality_profile_model is None:
|
if self._custom_quality_profile_drop_down_menu_model is None:
|
||||||
self._custom_quality_profile_model = CustomQualityProfilesModel(self)
|
self._custom_quality_profile_drop_down_menu_model = CustomQualityProfilesDropDownMenuModel(self)
|
||||||
return self._custom_quality_profile_model
|
return self._custom_quality_profile_drop_down_menu_model
|
||||||
|
|
||||||
## Registers objects for the QML engine to use.
|
## Registers objects for the QML engine to use.
|
||||||
#
|
#
|
||||||
|
@ -960,8 +961,10 @@ class CuraApplication(QtApplication):
|
||||||
qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel")
|
qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel")
|
||||||
qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
|
qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
|
||||||
|
|
||||||
qmlRegisterSingletonType(QualityProfilesModel, "Cura", 1, 0, "QualityProfilesModel", self.getQualityProfileModel)
|
qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0,
|
||||||
qmlRegisterSingletonType(CustomQualityProfilesModel, "Cura", 1, 0, "CustomQualityProfilesModel", self.getCustomQualityProfilesModel)
|
"QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel)
|
||||||
|
qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,
|
||||||
|
"CustomQualityProfilesDropDownMenuModel", self.getCustomQualityProfilesDropDownMenuModel)
|
||||||
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
|
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
|
||||||
|
|
||||||
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile.
|
# A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile.
|
||||||
# The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For
|
# The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For
|
||||||
|
|
|
@ -2,16 +2,24 @@
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from collections import defaultdict, OrderedDict
|
from collections import defaultdict, OrderedDict
|
||||||
from typing import Optional
|
import copy
|
||||||
|
import uuid
|
||||||
|
from typing import Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from PyQt5.Qt import QTimer, QObject, pyqtSignal
|
from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot
|
||||||
|
|
||||||
|
from UM.Application import Application
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Settings import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
from UM.Settings.SettingFunction import SettingFunction
|
||||||
|
from UM.Util import parseBool
|
||||||
|
|
||||||
from .MaterialNode import MaterialNode
|
from .MaterialNode import MaterialNode
|
||||||
from .MaterialGroup import MaterialGroup
|
from .MaterialGroup import MaterialGroup
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# MaterialManager maintains a number of maps and trees for material lookup.
|
# MaterialManager maintains a number of maps and trees for material lookup.
|
||||||
|
@ -29,6 +37,7 @@ class MaterialManager(QObject):
|
||||||
|
|
||||||
def __init__(self, container_registry, parent = None):
|
def __init__(self, container_registry, parent = None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
self._application = Application.getInstance()
|
||||||
self._container_registry = container_registry # type: ContainerRegistry
|
self._container_registry = container_registry # type: ContainerRegistry
|
||||||
|
|
||||||
self._fallback_materials_map = dict() # material_type -> generic material metadata
|
self._fallback_materials_map = dict() # material_type -> generic material metadata
|
||||||
|
@ -260,6 +269,20 @@ class MaterialManager(QObject):
|
||||||
|
|
||||||
return material_id_metadata_dict
|
return material_id_metadata_dict
|
||||||
|
|
||||||
|
#
|
||||||
|
# A convenience function to get available materials for the given machine with the extruder position.
|
||||||
|
#
|
||||||
|
def getAvailableMaterialsForMachineExtruder(self, machine: "GlobalStack",
|
||||||
|
extruder_stack: "ExtruderStack") -> Optional[dict]:
|
||||||
|
machine_definition_id = machine.definition.getId()
|
||||||
|
variant_name = None
|
||||||
|
if extruder_stack.variant.getId() != "empty_variant":
|
||||||
|
variant_name = extruder_stack.variant.getName()
|
||||||
|
diameter = extruder_stack.approximateMaterialDiameter
|
||||||
|
|
||||||
|
# Fetch the available materials (ContainerNode) for the current active machine and extruder setup.
|
||||||
|
return self.getAvailableMaterials(machine_definition_id, variant_name, diameter)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gets MaterialNode for the given extruder and machine with the given material name.
|
# Gets MaterialNode for the given extruder and machine with the given material name.
|
||||||
# Returns None if:
|
# Returns None if:
|
||||||
|
@ -315,7 +338,7 @@ class MaterialManager(QObject):
|
||||||
# This function returns the generic root material ID for the given material type, where material types are "PLA",
|
# This function returns the generic root material ID for the given material type, where material types are "PLA",
|
||||||
# "ABS", etc.
|
# "ABS", etc.
|
||||||
#
|
#
|
||||||
def getFallbackMaterialIdByMaterialType(self, material_type: str) -> str:
|
def getFallbackMaterialIdByMaterialType(self, material_type: str) -> Optional[str]:
|
||||||
# For safety
|
# For safety
|
||||||
if material_type not in self._fallback_materials_map:
|
if material_type not in self._fallback_materials_map:
|
||||||
Logger.log("w", "The material type [%s] does not have a fallback material" % material_type)
|
Logger.log("w", "The material type [%s] does not have a fallback material" % material_type)
|
||||||
|
@ -325,3 +348,132 @@ class MaterialManager(QObject):
|
||||||
return self.getRootMaterialIDWithoutDiameter(fallback_material["id"])
|
return self.getRootMaterialIDWithoutDiameter(fallback_material["id"])
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def getDefaultMaterial(self, global_stack: "GlobalStack", extruder_variant_name: str) -> Optional["MaterialNode"]:
|
||||||
|
node = None
|
||||||
|
machine_definition = global_stack.definition
|
||||||
|
if parseBool(machine_definition.getMetaDataEntry("has_materials", False)):
|
||||||
|
material_diameter = machine_definition.getProperty("material_diameter", "value")
|
||||||
|
if isinstance(material_diameter, SettingFunction):
|
||||||
|
material_diameter = material_diameter(global_stack)
|
||||||
|
approximate_material_diameter = str(round(material_diameter))
|
||||||
|
root_material_id = machine_definition.getMetaDataEntry("preferred_material")
|
||||||
|
root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter)
|
||||||
|
node = self.getMaterialNode(machine_definition.getId(), extruder_variant_name,
|
||||||
|
material_diameter, root_material_id)
|
||||||
|
return node
|
||||||
|
|
||||||
|
#
|
||||||
|
# Methods for GUI
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Sets the new name for the given material.
|
||||||
|
#
|
||||||
|
@pyqtSlot("QVariant", str)
|
||||||
|
def setMaterialName(self, material_node: "MaterialNode", name: str):
|
||||||
|
root_material_id = material_node.metadata["base_file"]
|
||||||
|
if self._container_registry.isReadOnly(root_material_id):
|
||||||
|
Logger.log("w", "Cannot set name of read-only container %s.", root_material_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
material_group = self.getMaterialGroup(root_material_id)
|
||||||
|
material_group.root_material_node.getContainer().setName(name)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Removes the given material.
|
||||||
|
#
|
||||||
|
@pyqtSlot("QVariant")
|
||||||
|
def removeMaterial(self, material_node: "MaterialNode"):
|
||||||
|
root_material_id = material_node.metadata["base_file"]
|
||||||
|
material_group = self.getMaterialGroup(root_material_id)
|
||||||
|
if not material_group:
|
||||||
|
Logger.log("d", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list
|
||||||
|
for node in nodes_to_remove:
|
||||||
|
self._container_registry.removeContainer(node.metadata["id"])
|
||||||
|
|
||||||
|
#
|
||||||
|
# Creates a duplicate of a material, which has the same GUID and base_file metadata.
|
||||||
|
# Returns the root material ID of the duplicated material if successful.
|
||||||
|
#
|
||||||
|
@pyqtSlot("QVariant", result = str)
|
||||||
|
def duplicateMaterial(self, material_node, new_base_id = None, new_metadata = None) -> Optional[str]:
|
||||||
|
root_material_id = material_node.metadata["base_file"]
|
||||||
|
|
||||||
|
material_group = self.getMaterialGroup(root_material_id)
|
||||||
|
if not material_group:
|
||||||
|
Logger.log("i", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
base_container = material_group.root_material_node.getContainer()
|
||||||
|
|
||||||
|
# Ensure all settings are saved.
|
||||||
|
self._application.saveSettings()
|
||||||
|
|
||||||
|
# Create a new ID & container to hold the data.
|
||||||
|
new_containers = []
|
||||||
|
if new_base_id is None:
|
||||||
|
new_base_id = self._container_registry.uniqueName(base_container.getId())
|
||||||
|
new_base_container = copy.deepcopy(base_container)
|
||||||
|
new_base_container.getMetaData()["id"] = new_base_id
|
||||||
|
new_base_container.getMetaData()["base_file"] = new_base_id
|
||||||
|
if new_metadata is not None:
|
||||||
|
for key, value in new_metadata.items():
|
||||||
|
new_base_container.getMetaData()[key] = value
|
||||||
|
new_containers.append(new_base_container)
|
||||||
|
|
||||||
|
# Clone all of them.
|
||||||
|
for node in material_group.derived_material_node_list:
|
||||||
|
container_to_copy = node.getContainer()
|
||||||
|
# Create unique IDs for every clone.
|
||||||
|
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_name"):
|
||||||
|
variant_name = container_to_copy.getMetaDataEntry("variant_name")
|
||||||
|
new_id += "_" + variant_name.replace(" ", "_")
|
||||||
|
|
||||||
|
new_container = copy.deepcopy(container_to_copy)
|
||||||
|
new_container.getMetaData()["id"] = new_id
|
||||||
|
new_container.getMetaData()["base_file"] = new_base_id
|
||||||
|
if new_metadata is not None:
|
||||||
|
for key, value in new_metadata.items():
|
||||||
|
new_container.getMetaData()[key] = value
|
||||||
|
|
||||||
|
new_containers.append(new_container)
|
||||||
|
|
||||||
|
for container_to_add in new_containers:
|
||||||
|
container_to_add.setDirty(True)
|
||||||
|
self._container_registry.addContainer(container_to_add)
|
||||||
|
return new_base_id
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create a new material by cloning Generic PLA for the current material diameter and generate a new GUID.
|
||||||
|
#
|
||||||
|
@pyqtSlot(result = str)
|
||||||
|
def createMaterial(self) -> str:
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
catalog = i18nCatalog("cura")
|
||||||
|
# Ensure all settings are saved.
|
||||||
|
self._application.saveSettings()
|
||||||
|
|
||||||
|
global_stack = self._application.getGlobalContainerStack()
|
||||||
|
approximate_diameter = str(round(global_stack.getProperty("material_diameter", "value")))
|
||||||
|
root_material_id = "generic_pla"
|
||||||
|
root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_diameter)
|
||||||
|
material_group = self.getMaterialGroup(root_material_id)
|
||||||
|
|
||||||
|
# Create a new ID & container to hold the data.
|
||||||
|
new_id = self._container_registry.uniqueName("custom_material")
|
||||||
|
new_metadata = {"name": catalog.i18nc("@label", "Custom Material"),
|
||||||
|
"brand": catalog.i18nc("@label", "Custom"),
|
||||||
|
"GUID": str(uuid.uuid4()),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.duplicateMaterial(material_group.root_material_node,
|
||||||
|
new_base_id = new_id,
|
||||||
|
new_metadata = new_metadata)
|
||||||
|
return new_id
|
||||||
|
|
|
@ -1,41 +1,17 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from typing import Optional
|
|
||||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
|
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
|
||||||
|
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
|
|
||||||
|
|
||||||
def getAvailableMaterials(extruder_position: Optional[int] = None):
|
#
|
||||||
from cura.CuraApplication import CuraApplication
|
# This is the base model class for GenericMaterialsModel and BrandMaterialsModel
|
||||||
machine_manager = CuraApplication.getInstance().getMachineManager()
|
# Those 2 models are used by the material drop down menu to show generic materials and branded materials separately.
|
||||||
extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
# The extruder position defined here is being used to bound a menu to the correct extruder. This is used in the top
|
||||||
material_manager = CuraApplication.getInstance().getMaterialManager()
|
# bar menu "Settings" -> "Extruder nr" -> "Material" -> this menu
|
||||||
|
#
|
||||||
active_global_stack = machine_manager.activeMachine
|
|
||||||
extruder_stack = extruder_manager.getActiveExtruderStack()
|
|
||||||
if extruder_position is not None:
|
|
||||||
if active_global_stack is not None:
|
|
||||||
extruder_stack = active_global_stack.extruders.get(str(extruder_position))
|
|
||||||
|
|
||||||
if active_global_stack is None or 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, extruder_stack)
|
|
||||||
return
|
|
||||||
|
|
||||||
machine_definition_id = active_global_stack.definition.getId()
|
|
||||||
variant_name = None
|
|
||||||
if extruder_stack.variant.getId() != "empty_variant":
|
|
||||||
variant_name = extruder_stack.variant.getName()
|
|
||||||
diameter = extruder_stack.approximateMaterialDiameter
|
|
||||||
|
|
||||||
# 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):
|
class BaseMaterialsModel(ListModel):
|
||||||
RootMaterialIdRole = Qt.UserRole + 1
|
RootMaterialIdRole = Qt.UserRole + 1
|
||||||
IdRole = Qt.UserRole + 2
|
IdRole = Qt.UserRole + 2
|
||||||
|
|
|
@ -5,9 +5,12 @@ from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
|
||||||
|
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
|
|
||||||
from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials
|
from .BaseMaterialsModel import BaseMaterialsModel
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# This is an intermediate model to group materials with different colours for a same brand and type.
|
||||||
|
#
|
||||||
class MaterialsModelGroupedByType(ListModel):
|
class MaterialsModelGroupedByType(ListModel):
|
||||||
NameRole = Qt.UserRole + 1
|
NameRole = Qt.UserRole + 1
|
||||||
ColorsRole = Qt.UserRole + 2
|
ColorsRole = Qt.UserRole + 2
|
||||||
|
@ -19,7 +22,18 @@ class MaterialsModelGroupedByType(ListModel):
|
||||||
self.addRoleName(self.ColorsRole, "colors")
|
self.addRoleName(self.ColorsRole, "colors")
|
||||||
|
|
||||||
|
|
||||||
## Brand --> Material Type -> list of materials
|
#
|
||||||
|
# This model is used to show branded materials in the material drop down menu.
|
||||||
|
# The structure of the menu looks like this:
|
||||||
|
# Brand -> Material Type -> list of materials
|
||||||
|
#
|
||||||
|
# To illustrate, a branded material menu may look like this:
|
||||||
|
# Ultimaker -> PLA -> Yellow PLA
|
||||||
|
# -> Black PLA
|
||||||
|
# -> ...
|
||||||
|
# -> ABS -> White ABS
|
||||||
|
# ...
|
||||||
|
#
|
||||||
class BrandMaterialsModel(ListModel):
|
class BrandMaterialsModel(ListModel):
|
||||||
NameRole = Qt.UserRole + 1
|
NameRole = Qt.UserRole + 1
|
||||||
MaterialsRole = Qt.UserRole + 2
|
MaterialsRole = Qt.UserRole + 2
|
||||||
|
@ -36,12 +50,12 @@ class BrandMaterialsModel(ListModel):
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
self._machine_manager = CuraApplication.getInstance().getMachineManager()
|
self._machine_manager = CuraApplication.getInstance().getMachineManager()
|
||||||
extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
||||||
material_manager = CuraApplication.getInstance().getMaterialManager()
|
self._material_manager = CuraApplication.getInstance().getMaterialManager()
|
||||||
|
|
||||||
self._machine_manager.globalContainerChanged.connect(self._update)
|
self._machine_manager.globalContainerChanged.connect(self._update)
|
||||||
extruder_manager.activeExtruderChanged.connect(self._update)
|
self._extruder_manager.activeExtruderChanged.connect(self._update)
|
||||||
material_manager.materialsUpdated.connect(self._update)
|
self._material_manager.materialsUpdated.connect(self._update)
|
||||||
|
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
|
@ -59,15 +73,21 @@ class BrandMaterialsModel(ListModel):
|
||||||
if global_stack is None:
|
if global_stack is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
return
|
return
|
||||||
|
extruder_position = str(self._extruder_position)
|
||||||
|
if extruder_position not in global_stack.extruders:
|
||||||
|
self.setItems([])
|
||||||
|
return
|
||||||
|
extruder_stack = global_stack.extruders[str(self._extruder_position)]
|
||||||
|
|
||||||
result_dict = getAvailableMaterials(self._extruder_position)
|
available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
|
||||||
if result_dict is None:
|
extruder_stack)
|
||||||
|
if available_material_dict is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
return
|
return
|
||||||
|
|
||||||
brand_item_list = []
|
brand_item_list = []
|
||||||
brand_group_dict = {}
|
brand_group_dict = {}
|
||||||
for root_material_id, container_node in result_dict.items():
|
for root_material_id, container_node in available_material_dict.items():
|
||||||
metadata = container_node.metadata
|
metadata = container_node.metadata
|
||||||
brand = metadata["brand"]
|
brand = metadata["brand"]
|
||||||
# Only add results for generic materials
|
# Only add results for generic materials
|
||||||
|
@ -109,4 +129,3 @@ class BrandMaterialsModel(ListModel):
|
||||||
brand_item_list.append(brand_item)
|
brand_item_list.append(brand_item)
|
||||||
|
|
||||||
self.setItems(brand_item_list)
|
self.setItems(brand_item_list)
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from UM.Application import Application
|
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
|
|
||||||
from cura.Machines.Models.QualityProfilesModel import QualityProfilesModel
|
from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# This model is used for the custom profile items in the profile drop down menu.
|
# This model is used for the custom profile items in the profile drop down menu.
|
||||||
#
|
#
|
||||||
class CustomQualityProfilesModel(QualityProfilesModel):
|
class CustomQualityProfilesDropDownMenuModel(QualityProfilesDropDownMenuModel):
|
||||||
|
|
||||||
def _update(self):
|
def _update(self):
|
||||||
Logger.log("d", "Updating %s ...", self.__class__.__name__)
|
Logger.log("d", "Updating %s ...", self.__class__.__name__)
|
||||||
|
|
||||||
active_global_stack = Application.getInstance().getMachineManager().activeMachine
|
active_global_stack = self._machine_manager.activeMachine
|
||||||
if active_global_stack is None:
|
if active_global_stack is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__)
|
Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__)
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from .BaseMaterialsModel import BaseMaterialsModel, getAvailableMaterials
|
from .BaseMaterialsModel import BaseMaterialsModel
|
||||||
|
|
||||||
|
|
||||||
class GenericMaterialsModel(BaseMaterialsModel):
|
class GenericMaterialsModel(BaseMaterialsModel):
|
||||||
|
@ -25,14 +25,20 @@ class GenericMaterialsModel(BaseMaterialsModel):
|
||||||
if global_stack is None:
|
if global_stack is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
return
|
return
|
||||||
|
extruder_position = str(self._extruder_position)
|
||||||
|
if extruder_position not in global_stack.extruders:
|
||||||
|
self.setItems([])
|
||||||
|
return
|
||||||
|
extruder_stack = global_stack.extruders[extruder_position]
|
||||||
|
|
||||||
result_dict = getAvailableMaterials(self._extruder_position)
|
available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
|
||||||
if result_dict is None:
|
extruder_stack)
|
||||||
|
if available_material_dict is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
return
|
return
|
||||||
|
|
||||||
item_list = []
|
item_list = []
|
||||||
for root_material_id, container_node in result_dict.items():
|
for root_material_id, container_node in available_material_dict.items():
|
||||||
metadata = container_node.metadata
|
metadata = container_node.metadata
|
||||||
# Only add results for generic materials
|
# Only add results for generic materials
|
||||||
if metadata["brand"].lower() != "generic":
|
if metadata["brand"].lower() != "generic":
|
||||||
|
|
|
@ -5,8 +5,6 @@ from PyQt5.QtCore import Qt, pyqtProperty
|
||||||
|
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
|
|
||||||
from .BaseMaterialsModel import getAvailableMaterials
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# This model is for the Material management page.
|
# This model is for the Material management page.
|
||||||
|
@ -52,12 +50,12 @@ class MaterialManagementModel(ListModel):
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
self._container_registry = CuraApplication.getInstance().getContainerRegistry()
|
self._container_registry = CuraApplication.getInstance().getContainerRegistry()
|
||||||
self._machine_manager = CuraApplication.getInstance().getMachineManager()
|
self._machine_manager = CuraApplication.getInstance().getMachineManager()
|
||||||
extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
||||||
material_manager = CuraApplication.getInstance().getMaterialManager()
|
self._material_manager = CuraApplication.getInstance().getMaterialManager()
|
||||||
|
|
||||||
self._machine_manager.globalContainerChanged.connect(self._update)
|
self._machine_manager.globalContainerChanged.connect(self._update)
|
||||||
extruder_manager.activeExtruderChanged.connect(self._update)
|
self._extruder_manager.activeExtruderChanged.connect(self._update)
|
||||||
material_manager.materialsUpdated.connect(self._update)
|
self._material_manager.materialsUpdated.connect(self._update)
|
||||||
|
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
|
@ -66,14 +64,16 @@ class MaterialManagementModel(ListModel):
|
||||||
if global_stack is None:
|
if global_stack is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
return
|
return
|
||||||
|
active_extruder_stack = self._machine_manager.activeStack
|
||||||
|
|
||||||
result_dict = getAvailableMaterials()
|
available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
|
||||||
if result_dict is None:
|
active_extruder_stack)
|
||||||
|
if available_material_dict is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
return
|
return
|
||||||
|
|
||||||
material_list = []
|
material_list = []
|
||||||
for root_material_id, container_node in result_dict.items():
|
for root_material_id, container_node in available_material_dict.items():
|
||||||
keys_to_fetch = ("name",
|
keys_to_fetch = ("name",
|
||||||
"brand",
|
"brand",
|
||||||
"material",
|
"material",
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty
|
from PyQt5.QtCore import pyqtSignal, pyqtProperty
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
@ -5,6 +8,10 @@ from UM.Scene.Selection import Selection
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# This is the model for multi build plate feature.
|
||||||
|
# This has nothing to do with the build plate types you can choose on the sidebar for a machine.
|
||||||
|
#
|
||||||
class MultiBuildPlateModel(ListModel):
|
class MultiBuildPlateModel(ListModel):
|
||||||
|
|
||||||
maxBuildPlateChanged = pyqtSignal()
|
maxBuildPlateChanged = pyqtSignal()
|
|
@ -6,6 +6,9 @@ from PyQt5.QtCore import Qt, pyqtSlot
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# This the QML model for the quality management page.
|
||||||
|
#
|
||||||
class QualityManagementModel(ListModel):
|
class QualityManagementModel(ListModel):
|
||||||
NameRole = Qt.UserRole + 1
|
NameRole = Qt.UserRole + 1
|
||||||
IsReadOnlyRole = Qt.UserRole + 2
|
IsReadOnlyRole = Qt.UserRole + 2
|
||||||
|
@ -24,7 +27,7 @@ class QualityManagementModel(ListModel):
|
||||||
self._container_registry = CuraApplication.getInstance().getContainerRegistry()
|
self._container_registry = CuraApplication.getInstance().getContainerRegistry()
|
||||||
self._machine_manager = CuraApplication.getInstance().getMachineManager()
|
self._machine_manager = CuraApplication.getInstance().getMachineManager()
|
||||||
self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
||||||
self._quality_manager = CuraApplication.getInstance()._quality_manager
|
self._quality_manager = CuraApplication.getInstance().getQualityManager()
|
||||||
|
|
||||||
self._machine_manager.globalContainerChanged.connect(self._update)
|
self._machine_manager.globalContainerChanged.connect(self._update)
|
||||||
self._quality_manager.qualitiesUpdated.connect(self._update)
|
self._quality_manager.qualitiesUpdated.connect(self._update)
|
||||||
|
@ -32,12 +35,13 @@ class QualityManagementModel(ListModel):
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
def _update(self):
|
def _update(self):
|
||||||
global_stack = self._machine_manager._global_container_stack
|
global_stack = self._machine_manager.activeMachine
|
||||||
|
|
||||||
quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
|
quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
|
||||||
quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack)
|
quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack)
|
||||||
|
|
||||||
available_quality_types = set(qt for qt, qg in quality_group_dict.items() if qg.is_available)
|
available_quality_types = set(quality_type for quality_type, quality_group in quality_group_dict.items()
|
||||||
|
if quality_group.is_available)
|
||||||
if not available_quality_types and not quality_changes_group_dict:
|
if not available_quality_types and not quality_changes_group_dict:
|
||||||
# Nothing to show
|
# Nothing to show
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
|
|
|
@ -6,17 +6,18 @@ from PyQt5.QtCore import Qt
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
|
|
||||||
from cura.Machines.QualityManager import QualityGroup
|
from cura.Machines.QualityManager import QualityGroup
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# QML Model for all built-in quality profiles.
|
# QML Model for all built-in quality profiles. This model is used for the drop-down quality menu.
|
||||||
#
|
#
|
||||||
class QualityProfilesModel(ListModel):
|
class QualityProfilesDropDownMenuModel(ListModel):
|
||||||
NameRole = Qt.UserRole + 1
|
NameRole = Qt.UserRole + 1
|
||||||
QualityTypeRole = Qt.UserRole + 2
|
QualityTypeRole = Qt.UserRole + 2
|
||||||
LayerHeightRole = Qt.UserRole + 3
|
LayerHeightRole = Qt.UserRole + 3
|
||||||
LayerHeightWithoutUnitRole = Qt.UserRole + 4
|
LayerHeightUnitRole = Qt.UserRole + 4
|
||||||
AvailableRole = Qt.UserRole + 5
|
AvailableRole = Qt.UserRole + 5
|
||||||
QualityGroupRole = Qt.UserRole + 6
|
QualityGroupRole = Qt.UserRole + 6
|
||||||
QualityChangesGroupRole = Qt.UserRole + 7
|
QualityChangesGroupRole = Qt.UserRole + 7
|
||||||
|
@ -27,17 +28,18 @@ class QualityProfilesModel(ListModel):
|
||||||
self.addRoleName(self.NameRole, "name")
|
self.addRoleName(self.NameRole, "name")
|
||||||
self.addRoleName(self.QualityTypeRole, "quality_type")
|
self.addRoleName(self.QualityTypeRole, "quality_type")
|
||||||
self.addRoleName(self.LayerHeightRole, "layer_height")
|
self.addRoleName(self.LayerHeightRole, "layer_height")
|
||||||
self.addRoleName(self.LayerHeightWithoutUnitRole, "layer_height_without_unit")
|
self.addRoleName(self.LayerHeightUnitRole, "layer_height_unit")
|
||||||
self.addRoleName(self.AvailableRole, "available")
|
self.addRoleName(self.AvailableRole, "available")
|
||||||
self.addRoleName(self.QualityGroupRole, "quality_group")
|
self.addRoleName(self.QualityGroupRole, "quality_group")
|
||||||
self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
|
self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
|
||||||
|
|
||||||
# connect signals
|
self._application = Application.getInstance()
|
||||||
Application.getInstance().globalContainerStackChanged.connect(self._update)
|
self._machine_manager = self._application.getMachineManager()
|
||||||
Application.getInstance().getMachineManager().activeQualityGroupChanged.connect(self._update)
|
self._quality_manager = Application.getInstance().getQualityManager()
|
||||||
Application.getInstance().getMachineManager().extruderChanged.connect(self._update)
|
|
||||||
|
|
||||||
self._quality_manager = Application.getInstance()._quality_manager
|
self._application.globalContainerStackChanged.connect(self._update)
|
||||||
|
self._machine_manager.activeQualityGroupChanged.connect(self._update)
|
||||||
|
self._machine_manager.extruderChanged.connect(self._update)
|
||||||
self._quality_manager.qualitiesUpdated.connect(self._update)
|
self._quality_manager.qualitiesUpdated.connect(self._update)
|
||||||
|
|
||||||
self._layer_height_unit = "" # This is cached
|
self._layer_height_unit = "" # This is cached
|
||||||
|
@ -47,15 +49,15 @@ class QualityProfilesModel(ListModel):
|
||||||
def _update(self):
|
def _update(self):
|
||||||
Logger.log("d", "Updating quality profile model ...")
|
Logger.log("d", "Updating quality profile model ...")
|
||||||
|
|
||||||
machine_manager = Application.getInstance().getMachineManager()
|
global_stack = self._machine_manager.activeMachine
|
||||||
global_stack = machine_manager._global_container_stack
|
|
||||||
if global_stack is None:
|
if global_stack is None:
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
|
Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check for material compatibility
|
# Check for material compatibility
|
||||||
if not machine_manager.activeMaterialsCompatible():
|
if not self._machine_manager.activeMaterialsCompatible():
|
||||||
|
Logger.log("d", "No active material compatibility, set quality profile model as empty.")
|
||||||
self.setItems([])
|
self.setItems([])
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -69,20 +71,20 @@ class QualityProfilesModel(ListModel):
|
||||||
|
|
||||||
item = {"name": quality_group.name,
|
item = {"name": quality_group.name,
|
||||||
"quality_type": quality_group.quality_type,
|
"quality_type": quality_group.quality_type,
|
||||||
"layer_height": layer_height + self._layer_height_unit,
|
"layer_height": layer_height,
|
||||||
"layer_height_without_unit": layer_height,
|
"layer_height_unit": self._layer_height_unit,
|
||||||
"available": quality_group.is_available,
|
"available": quality_group.is_available,
|
||||||
"quality_group": quality_group}
|
"quality_group": quality_group}
|
||||||
|
|
||||||
item_list.append(item)
|
item_list.append(item)
|
||||||
|
|
||||||
# Sort items based on layer_height
|
# Sort items based on layer_height
|
||||||
item_list = sorted(item_list, key = lambda x: float(x["layer_height_without_unit"]))
|
item_list = sorted(item_list, key = lambda x: x["layer_height"])
|
||||||
|
|
||||||
self.setItems(item_list)
|
self.setItems(item_list)
|
||||||
|
|
||||||
def _fetchLayerHeight(self, quality_group: "QualityGroup"):
|
def _fetchLayerHeight(self, quality_group: "QualityGroup"):
|
||||||
global_stack = Application.getInstance().getMachineManager()._global_container_stack
|
global_stack = self._machine_manager.activeMachine
|
||||||
if not self._layer_height_unit:
|
if not self._layer_height_unit:
|
||||||
unit = global_stack.definition.getProperty("layer_height", "unit")
|
unit = global_stack.definition.getProperty("layer_height", "unit")
|
||||||
if not unit:
|
if not unit:
|
||||||
|
@ -96,10 +98,10 @@ class QualityProfilesModel(ListModel):
|
||||||
|
|
||||||
layer_height = default_layer_height
|
layer_height = default_layer_height
|
||||||
if container.hasProperty("layer_height", "value"):
|
if container.hasProperty("layer_height", "value"):
|
||||||
layer_height = str(container.getProperty("layer_height", "value"))
|
layer_height = container.getProperty("layer_height", "value")
|
||||||
else:
|
else:
|
||||||
# Look for layer_height in the GlobalStack from material -> definition
|
# Look for layer_height in the GlobalStack from material -> definition
|
||||||
container = global_stack.definition
|
container = global_stack.definition
|
||||||
if container.hasProperty("layer_height", "value"):
|
if container.hasProperty("layer_height", "value"):
|
||||||
layer_height = container.getProperty("layer_height", "value")
|
layer_height = container.getProperty("layer_height", "value")
|
||||||
return str(layer_height)
|
return float(layer_height)
|
|
@ -4,6 +4,7 @@
|
||||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
|
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
from UM.Logger import Logger
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
|
||||||
|
@ -33,9 +34,10 @@ class QualitySettingsModel(ListModel):
|
||||||
|
|
||||||
self._container_registry = ContainerRegistry.getInstance()
|
self._container_registry = ContainerRegistry.getInstance()
|
||||||
self._application = Application.getInstance()
|
self._application = Application.getInstance()
|
||||||
self._quality_manager = self._application._quality_manager
|
self._quality_manager = self._application.getQualityManager()
|
||||||
|
|
||||||
self._extruder_position = ""
|
self._selected_position = "" # empty string means GlobalStack
|
||||||
|
# strings such as "0", "1", etc. mean extruder positions
|
||||||
self._selected_quality_item = None # The selected quality in the quality management page
|
self._selected_quality_item = None # The selected quality in the quality management page
|
||||||
self._i18n_catalog = None
|
self._i18n_catalog = None
|
||||||
|
|
||||||
|
@ -43,18 +45,18 @@ class QualitySettingsModel(ListModel):
|
||||||
|
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
extruderPositionChanged = pyqtSignal()
|
selectedPositionChanged = pyqtSignal()
|
||||||
selectedQualityItemChanged = pyqtSignal()
|
selectedQualityItemChanged = pyqtSignal()
|
||||||
|
|
||||||
def setExtruderPosition(self, extruder_position):
|
def setSelectedPosition(self, selected_position):
|
||||||
if extruder_position != self._extruder_position:
|
if selected_position != self._selected_position:
|
||||||
self._extruder_position = extruder_position
|
self._selected_position = selected_position
|
||||||
self.extruderPositionChanged.emit()
|
self.selectedPositionChanged.emit()
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
@pyqtProperty(str, fset = setExtruderPosition, notify = extruderPositionChanged)
|
@pyqtProperty(str, fset = setSelectedPosition, notify = selectedPositionChanged)
|
||||||
def extruderPosition(self):
|
def selectedPosition(self):
|
||||||
return self._extruder_position
|
return self._selected_position
|
||||||
|
|
||||||
def setSelectedQualityItem(self, selected_quality_item):
|
def setSelectedQualityItem(self, selected_quality_item):
|
||||||
if selected_quality_item != self._selected_quality_item:
|
if selected_quality_item != self._selected_quality_item:
|
||||||
|
@ -73,32 +75,38 @@ class QualitySettingsModel(ListModel):
|
||||||
|
|
||||||
items = []
|
items = []
|
||||||
|
|
||||||
global_container_stack = Application.getInstance().getGlobalContainerStack()
|
global_container_stack = self._application.getGlobalContainerStack()
|
||||||
definition_container = global_container_stack.definition
|
definition_container = global_container_stack.definition
|
||||||
|
|
||||||
quality_group = self._selected_quality_item["quality_group"]
|
quality_group = self._selected_quality_item["quality_group"]
|
||||||
quality_changes_group = self._selected_quality_item["quality_changes_group"]
|
quality_changes_group = self._selected_quality_item["quality_changes_group"]
|
||||||
|
|
||||||
if self._extruder_position == "":
|
if self._selected_position == "":
|
||||||
quality_node = quality_group.node_for_global
|
quality_node = quality_group.node_for_global
|
||||||
else:
|
else:
|
||||||
quality_node = quality_group.nodes_for_extruders.get(self._extruder_position)
|
quality_node = quality_group.nodes_for_extruders.get(self._selected_position)
|
||||||
settings_keys = quality_group.getAllKeys()
|
settings_keys = quality_group.getAllKeys()
|
||||||
quality_containers = [quality_node.getContainer()]
|
quality_containers = [quality_node.getContainer()]
|
||||||
|
|
||||||
|
# Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch
|
||||||
|
# the settings in that quality_changes_group.
|
||||||
if quality_changes_group is not None:
|
if quality_changes_group is not None:
|
||||||
if self._extruder_position == "":
|
if self._selected_position == "":
|
||||||
quality_changes_node = quality_changes_group.node_for_global
|
quality_changes_node = quality_changes_group.node_for_global
|
||||||
else:
|
else:
|
||||||
quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._extruder_position)
|
quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._selected_position)
|
||||||
if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime
|
if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime
|
||||||
try:
|
try:
|
||||||
quality_containers.insert(0, quality_changes_node.getContainer())
|
quality_containers.insert(0, quality_changes_node.getContainer())
|
||||||
except:
|
except:
|
||||||
# FIXME: This is to prevent incomplete update of QualityManager
|
# FIXME: This is to prevent incomplete update of QualityManager
|
||||||
|
Logger.logException("d", "Failed to get container for quality changes node %s", quality_changes_node)
|
||||||
return
|
return
|
||||||
settings_keys.update(quality_changes_group.getAllKeys())
|
settings_keys.update(quality_changes_group.getAllKeys())
|
||||||
|
|
||||||
|
# We iterate over all definitions instead of settings in a quality/qualtiy_changes group is because in the GUI,
|
||||||
|
# the settings are grouped together by categories, and we had to go over all the definitions to figure out
|
||||||
|
# which setting belongs in which category.
|
||||||
current_category = ""
|
current_category = ""
|
||||||
for definition in definition_container.findDefinitions():
|
for definition in definition_container.findDefinitions():
|
||||||
if definition.type == "category":
|
if definition.type == "category":
|
||||||
|
@ -117,7 +125,7 @@ class QualitySettingsModel(ListModel):
|
||||||
profile_value = new_value
|
profile_value = new_value
|
||||||
|
|
||||||
# Global tab should use resolve (if there is one)
|
# Global tab should use resolve (if there is one)
|
||||||
if self._extruder_position == "":
|
if self._selected_position == "":
|
||||||
resolve_value = global_container_stack.getProperty(definition.key, "resolve")
|
resolve_value = global_container_stack.getProperty(definition.key, "resolve")
|
||||||
if resolve_value is not None and definition.key in settings_keys:
|
if resolve_value is not None and definition.key in settings_keys:
|
||||||
profile_value = resolve_value
|
profile_value = resolve_value
|
||||||
|
@ -125,10 +133,10 @@ class QualitySettingsModel(ListModel):
|
||||||
if profile_value is not None:
|
if profile_value is not None:
|
||||||
break
|
break
|
||||||
|
|
||||||
if not self._extruder_position:
|
if not self._selected_position:
|
||||||
user_value = global_container_stack.userChanges.getProperty(definition.key, "value")
|
user_value = global_container_stack.userChanges.getProperty(definition.key, "value")
|
||||||
else:
|
else:
|
||||||
extruder_stack = global_container_stack.extruders[self._extruder_position]
|
extruder_stack = global_container_stack.extruders[self._selected_position]
|
||||||
user_value = extruder_stack.userChanges.getProperty(definition.key, "value")
|
user_value = extruder_stack.userChanges.getProperty(definition.key, "value")
|
||||||
|
|
||||||
if profile_value is None and user_value is None:
|
if profile_value is None and user_value is None:
|
||||||
|
|
53
cura/Machines/QualityChangesGroup.py
Normal file
53
cura/Machines/QualityChangesGroup.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from UM.Application import Application
|
||||||
|
|
||||||
|
from .QualityGroup import QualityGroup
|
||||||
|
|
||||||
|
|
||||||
|
class QualityChangesGroup(QualityGroup):
|
||||||
|
|
||||||
|
def __init__(self, name: str, quality_type: str, parent = None):
|
||||||
|
super().__init__(name, quality_type, parent)
|
||||||
|
self._container_registry = Application.getInstance().getContainerRegistry()
|
||||||
|
|
||||||
|
def addNode(self, node: "QualityNode"):
|
||||||
|
# TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the
|
||||||
|
# extruder definition ID it belongs to. But, in fact, we only need to know the following things:
|
||||||
|
# 1. which machine a custom profile is suitable for,
|
||||||
|
# 2. if this profile is for the GlobalStack,
|
||||||
|
# 3. if this profile is for an ExtruderStack and which one (the position).
|
||||||
|
#
|
||||||
|
# So, it is preferred to have a field like this:
|
||||||
|
# extruder_position = 1
|
||||||
|
# instead of this:
|
||||||
|
# extruder = custom_extruder_1
|
||||||
|
#
|
||||||
|
# An upgrade needs to be done if we want to do it this way. Before that, we use the extruder's definition
|
||||||
|
# to figure out its position.
|
||||||
|
#
|
||||||
|
extruder_definition_id = node.metadata.get("extruder")
|
||||||
|
if extruder_definition_id:
|
||||||
|
metadata_list = self._container_registry.findDefinitionContainersMetadata(id = extruder_definition_id)
|
||||||
|
if not metadata_list:
|
||||||
|
raise RuntimeError("%s cannot get metadata for extruder definition [%s]" %
|
||||||
|
(self, extruder_definition_id))
|
||||||
|
extruder_definition_metadata = metadata_list[0]
|
||||||
|
extruder_position = str(extruder_definition_metadata["position"])
|
||||||
|
|
||||||
|
if extruder_position in self.nodes_for_extruders:
|
||||||
|
raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" %
|
||||||
|
(self, extruder_position, self.node_for_global, node))
|
||||||
|
|
||||||
|
self.nodes_for_extruders[extruder_position] = node
|
||||||
|
|
||||||
|
else:
|
||||||
|
# This is a quality_changes for the GlobalStack
|
||||||
|
if self.node_for_global is not None:
|
||||||
|
raise RuntimeError("%s tries to overwrite the existing node_for_global %s with %s" %
|
||||||
|
(self, self.node_for_global, node))
|
||||||
|
self.node_for_global = node
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available)
|
50
cura/Machines/QualityGroup.py
Normal file
50
cura/Machines/QualityGroup.py
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from typing import Optional, List
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QObject, pyqtSlot
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used.
|
||||||
|
# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type
|
||||||
|
# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3
|
||||||
|
# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look
|
||||||
|
# as below:
|
||||||
|
# GlobalStack ExtruderStack 1 ExtruderStack 2
|
||||||
|
# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal
|
||||||
|
#
|
||||||
|
# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to
|
||||||
|
# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead
|
||||||
|
# of looking them up again.
|
||||||
|
#
|
||||||
|
class QualityGroup(QObject):
|
||||||
|
|
||||||
|
def __init__(self, name: str, quality_type: str, parent = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.name = name
|
||||||
|
self.node_for_global = None # type: Optional["QualityGroup"]
|
||||||
|
self.nodes_for_extruders = dict() # position str -> QualityGroup
|
||||||
|
self.quality_type = quality_type
|
||||||
|
self.is_available = False
|
||||||
|
|
||||||
|
@pyqtSlot(result = str)
|
||||||
|
def getName(self) -> str:
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def getAllKeys(self) -> set:
|
||||||
|
result = set()
|
||||||
|
for node in [self.node_for_global] + list(self.nodes_for_extruders.values()):
|
||||||
|
if node is None:
|
||||||
|
continue
|
||||||
|
result.update(node.getContainer().getAllKeys())
|
||||||
|
return result
|
||||||
|
|
||||||
|
def getAllNodes(self) -> List["QualityGroup"]:
|
||||||
|
result = []
|
||||||
|
if self.node_for_global is not None:
|
||||||
|
result.append(self.node_for_global)
|
||||||
|
for extruder_node in self.nodes_for_extruders.values():
|
||||||
|
result.append(extruder_node)
|
||||||
|
return result
|
|
@ -1,154 +1,27 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from typing import Optional, List
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Util import parseBool
|
from UM.Util import parseBool
|
||||||
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
|
|
||||||
from cura.Machines.ContainerNode import ContainerNode
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
|
|
||||||
|
from .QualityGroup import QualityGroup
|
||||||
|
from .QualityNode import QualityNode
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
from .QualityChangesGroup import QualityChangesGroup
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Quality lookup tree structure:
|
# Similar to MaterialManager, QualityManager maintains a number of maps and trees for quality profile lookup.
|
||||||
#
|
|
||||||
# <machine_definition_id>------|
|
|
||||||
# | |
|
|
||||||
# <variant_name> <root_material_id>
|
|
||||||
# |
|
|
||||||
# <root_material_id>
|
|
||||||
# |
|
|
||||||
# <quality_type>
|
|
||||||
# |
|
|
||||||
# <quality_name>
|
|
||||||
# + <quality_changes_name>
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used.
|
|
||||||
# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type
|
|
||||||
# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3
|
|
||||||
# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look
|
|
||||||
# as below:
|
|
||||||
# GlobalStack ExtruderStack 1 ExtruderStack 2
|
|
||||||
# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal
|
|
||||||
#
|
|
||||||
# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to
|
|
||||||
# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead
|
|
||||||
# of looking them up again.
|
|
||||||
#
|
|
||||||
class QualityGroup(QObject):
|
|
||||||
|
|
||||||
def __init__(self, name: str, quality_type: str, parent = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self.name = name
|
|
||||||
self.node_for_global = None # type: Optional["QualityGroup"]
|
|
||||||
self.nodes_for_extruders = dict() # position str -> QualityGroup
|
|
||||||
self.quality_type = quality_type
|
|
||||||
self.is_available = False
|
|
||||||
|
|
||||||
@pyqtSlot(result = str)
|
|
||||||
def getName(self) -> str:
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
def getAllKeys(self) -> set:
|
|
||||||
result = set()
|
|
||||||
for node in [self.node_for_global] + list(self.nodes_for_extruders.values()):
|
|
||||||
if node is None:
|
|
||||||
continue
|
|
||||||
for key in node.getContainer().getAllKeys():
|
|
||||||
result.add(key)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def getAllNodes(self) -> List["QualityGroup"]:
|
|
||||||
result = []
|
|
||||||
if self.node_for_global is not None:
|
|
||||||
result.append(self.node_for_global)
|
|
||||||
for extruder_node in self.nodes_for_extruders.values():
|
|
||||||
result.append(extruder_node)
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class QualityChangesGroup(QualityGroup):
|
|
||||||
|
|
||||||
def __init__(self, name: str, quality_type: str, parent = None):
|
|
||||||
super().__init__(name, quality_type, parent)
|
|
||||||
|
|
||||||
def addNode(self, node: "QualityNode"):
|
|
||||||
# TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the
|
|
||||||
# extruder definition ID it belongs to. But, in fact, we only need to know the following things:
|
|
||||||
# 1. which machine a custom profile is suitable for,
|
|
||||||
# 2. if this profile is for the GlobalStack,
|
|
||||||
# 3. if this profile is for an ExtruderStack and which one (the position).
|
|
||||||
#
|
|
||||||
# So, it is preferred to have a field like this:
|
|
||||||
# extruder_position = 1
|
|
||||||
# instead of this:
|
|
||||||
# extruder = custom_extruder_1
|
|
||||||
#
|
|
||||||
# An upgrade needs to be done if we want to do it this way. Before that, we use the extruder's definition
|
|
||||||
# to figure out its position.
|
|
||||||
#
|
|
||||||
extruder_definition_id = node.metadata.get("extruder")
|
|
||||||
if extruder_definition_id:
|
|
||||||
container_registry = Application.getInstance().getContainerRegistry()
|
|
||||||
metadata_list = container_registry.findDefinitionContainersMetadata(id = extruder_definition_id)
|
|
||||||
if not metadata_list:
|
|
||||||
raise RuntimeError("%s cannot get metadata for extruder definition [%s]" %
|
|
||||||
(self, extruder_definition_id))
|
|
||||||
extruder_definition_metadata = metadata_list[0]
|
|
||||||
extruder_position = str(extruder_definition_metadata["position"])
|
|
||||||
|
|
||||||
if extruder_position in self.nodes_for_extruders:
|
|
||||||
raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" %
|
|
||||||
(self, extruder_position, self.node_for_global, node))
|
|
||||||
|
|
||||||
self.nodes_for_extruders[extruder_position] = node
|
|
||||||
|
|
||||||
else:
|
|
||||||
# This is a quality_changes for the GlobalStack
|
|
||||||
if self.node_for_global is not None:
|
|
||||||
raise RuntimeError("%s tries to overwrite the existing node_for_global %s with %s" %
|
|
||||||
(self, self.node_for_global, node))
|
|
||||||
self.node_for_global = node
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# QualityNode is used for BOTH quality and quality_changes containers.
|
|
||||||
#
|
|
||||||
class QualityNode(ContainerNode):
|
|
||||||
|
|
||||||
def __init__(self, metadata: Optional[dict] = None):
|
|
||||||
super().__init__(metadata = metadata)
|
|
||||||
self.quality_type_map = {} # quality_type -> QualityNode for InstanceContainer
|
|
||||||
|
|
||||||
def addQualityMetadata(self, quality_type: str, metadata: dict):
|
|
||||||
if quality_type not in self.quality_type_map:
|
|
||||||
self.quality_type_map[quality_type] = QualityNode(metadata)
|
|
||||||
|
|
||||||
def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]:
|
|
||||||
return self.quality_type_map.get(quality_type)
|
|
||||||
|
|
||||||
def addQualityChangesMetadata(self, quality_type: str, metadata: dict):
|
|
||||||
if quality_type not in self.quality_type_map:
|
|
||||||
self.quality_type_map[quality_type] = QualityNode()
|
|
||||||
quality_type_node = self.quality_type_map[quality_type]
|
|
||||||
|
|
||||||
name = metadata["name"]
|
|
||||||
if name not in quality_type_node.children_map:
|
|
||||||
quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type)
|
|
||||||
quality_changes_group = quality_type_node.children_map[name]
|
|
||||||
quality_changes_group.addNode(QualityNode(metadata))
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Similar to MaterialManager, QualityManager maintains a number of maps and trees for material lookup.
|
|
||||||
# The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in
|
# The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in
|
||||||
# QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI.
|
# QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI.
|
||||||
#
|
#
|
||||||
|
@ -164,7 +37,7 @@ class QualityManager(QObject):
|
||||||
def __init__(self, container_registry, parent = None):
|
def __init__(self, container_registry, parent = None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._application = Application.getInstance()
|
self._application = Application.getInstance()
|
||||||
self._material_manager = self._application._material_manager
|
self._material_manager = self._application.getMaterialManager()
|
||||||
self._container_registry = container_registry
|
self._container_registry = container_registry
|
||||||
|
|
||||||
self._empty_quality_container = self._application.empty_quality_container
|
self._empty_quality_container = self._application.empty_quality_container
|
||||||
|
@ -305,7 +178,6 @@ class QualityManager(QObject):
|
||||||
|
|
||||||
# Returns a dict of "custom profile name" -> QualityChangesGroup
|
# Returns a dict of "custom profile name" -> QualityChangesGroup
|
||||||
def getQualityChangesGroups(self, machine: "GlobalStack") -> dict:
|
def getQualityChangesGroups(self, machine: "GlobalStack") -> dict:
|
||||||
# Get machine definition ID for quality search
|
|
||||||
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
||||||
|
|
||||||
machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id)
|
machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id)
|
||||||
|
@ -327,9 +199,15 @@ class QualityManager(QObject):
|
||||||
|
|
||||||
return quality_changes_group_dict
|
return quality_changes_group_dict
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gets all quality groups for the given machine. Both available and none available ones will be included.
|
||||||
|
# It returns a dictionary with "quality_type"s as keys and "QualityGroup"s as values.
|
||||||
|
# Whether a QualityGroup is available can be unknown via the field QualityGroup.is_available.
|
||||||
|
# For more details, see QualityGroup.
|
||||||
|
#
|
||||||
def getQualityGroups(self, machine: "GlobalStack") -> dict:
|
def getQualityGroups(self, machine: "GlobalStack") -> dict:
|
||||||
# Get machine definition ID for quality search
|
|
||||||
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
||||||
|
|
||||||
# This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks
|
# This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks
|
||||||
has_variant_materials = parseBool(machine.getMetaDataEntry("has_variant_materials", False))
|
has_variant_materials = parseBool(machine.getMetaDataEntry("has_variant_materials", False))
|
||||||
|
|
||||||
|
@ -380,6 +258,17 @@ class QualityManager(QObject):
|
||||||
if fallback_root_material_id:
|
if fallback_root_material_id:
|
||||||
root_material_id_list.append(fallback_root_material_id)
|
root_material_id_list.append(fallback_root_material_id)
|
||||||
|
|
||||||
|
# Here we construct a list of nodes we want to look for qualities with the highest priority first.
|
||||||
|
# The use case is that, when we look for qualities for a machine, we first want to search in the following
|
||||||
|
# order:
|
||||||
|
# 1. machine-variant-and-material-specific qualities if exist
|
||||||
|
# 2. machine-variant-specific qualities if exist
|
||||||
|
# 3. machine-material-specific qualities if exist
|
||||||
|
# 4. machine-specific qualities if exist
|
||||||
|
# 5. generic qualities if exist
|
||||||
|
# Each points above can be represented as a node in the lookup tree, so here we simply put those nodes into
|
||||||
|
# the list with priorities as the order. Later, we just need to loop over each node in this list and fetch
|
||||||
|
# qualities from there.
|
||||||
nodes_to_check = []
|
nodes_to_check = []
|
||||||
|
|
||||||
if variant_name:
|
if variant_name:
|
||||||
|
@ -426,7 +315,6 @@ class QualityManager(QObject):
|
||||||
return quality_group_dict
|
return quality_group_dict
|
||||||
|
|
||||||
def getQualityGroupsForMachineDefinition(self, machine: "GlobalStack") -> dict:
|
def getQualityGroupsForMachineDefinition(self, machine: "GlobalStack") -> dict:
|
||||||
# Get machine definition ID for quality search
|
|
||||||
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
||||||
|
|
||||||
# To find the quality container for the GlobalStack, check in the following fall-back manner:
|
# To find the quality container for the GlobalStack, check in the following fall-back manner:
|
||||||
|
@ -449,6 +337,135 @@ class QualityManager(QObject):
|
||||||
|
|
||||||
return quality_group_dict
|
return quality_group_dict
|
||||||
|
|
||||||
|
#
|
||||||
|
# Methods for GUI
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Remove the given quality changes group.
|
||||||
|
#
|
||||||
|
@pyqtSlot(QObject)
|
||||||
|
def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup"):
|
||||||
|
Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name)
|
||||||
|
for node in quality_changes_group.getAllNodes():
|
||||||
|
self._container_registry.removeContainer(node.metadata["id"])
|
||||||
|
|
||||||
|
#
|
||||||
|
# Rename a set of quality changes containers. Returns the new name.
|
||||||
|
#
|
||||||
|
@pyqtSlot(QObject, str, result = str)
|
||||||
|
def renameQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", new_name: str) -> str:
|
||||||
|
Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name)
|
||||||
|
if new_name == quality_changes_group.name:
|
||||||
|
Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name)
|
||||||
|
return new_name
|
||||||
|
|
||||||
|
new_name = self._container_registry.uniqueName(new_name)
|
||||||
|
for node in quality_changes_group.getAllNodes():
|
||||||
|
node.getContainer().setName(new_name)
|
||||||
|
|
||||||
|
quality_changes_group.name = new_name
|
||||||
|
|
||||||
|
self._application.getMachineManager().activeQualityChanged.emit()
|
||||||
|
self._application.getMachineManager().activeQualityGroupChanged.emit()
|
||||||
|
|
||||||
|
return new_name
|
||||||
|
|
||||||
|
#
|
||||||
|
# Duplicates the given quality.
|
||||||
|
#
|
||||||
|
@pyqtSlot(str, "QVariantMap")
|
||||||
|
def duplicateQualityChanges(self, quality_changes_name, quality_model_item):
|
||||||
|
global_stack = self._application.getGlobalContainerStack()
|
||||||
|
if not global_stack:
|
||||||
|
Logger.log("i", "No active global stack, cannot duplicate quality changes.")
|
||||||
|
return
|
||||||
|
|
||||||
|
quality_group = quality_model_item["quality_group"]
|
||||||
|
quality_changes_group = quality_model_item["quality_changes_group"]
|
||||||
|
if quality_changes_group is None:
|
||||||
|
# create global quality changes only
|
||||||
|
new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name,
|
||||||
|
global_stack, extruder_id = None)
|
||||||
|
self._container_registry.addContainer(new_quality_changes)
|
||||||
|
else:
|
||||||
|
new_name = self._container_registry.uniqueName(quality_changes_name)
|
||||||
|
for node in quality_changes_group.getAllNodes():
|
||||||
|
container = node.getContainer()
|
||||||
|
new_id = self._container_registry.uniqueName(container.getId())
|
||||||
|
self._container_registry.addContainer(container.duplicate(new_id, new_name))
|
||||||
|
|
||||||
|
## Create quality changes containers from the user containers in the active stacks.
|
||||||
|
#
|
||||||
|
# This will go through the global and extruder stacks and create quality_changes containers from
|
||||||
|
# the user containers in each stack. These then replace the quality_changes containers in the
|
||||||
|
# stack and clear the user settings.
|
||||||
|
@pyqtSlot(str)
|
||||||
|
def createQualityChanges(self, base_name):
|
||||||
|
machine_manager = Application.getInstance().getMachineManager()
|
||||||
|
|
||||||
|
global_stack = machine_manager.activeMachine
|
||||||
|
if not global_stack:
|
||||||
|
return
|
||||||
|
|
||||||
|
active_quality_name = machine_manager.activeQualityOrQualityChangesName
|
||||||
|
if active_quality_name == "":
|
||||||
|
Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
|
||||||
|
return
|
||||||
|
|
||||||
|
machine_manager.blurSettings.emit()
|
||||||
|
if base_name is None or base_name == "":
|
||||||
|
base_name = active_quality_name
|
||||||
|
unique_name = self._container_registry.uniqueName(base_name)
|
||||||
|
|
||||||
|
# Go through the active stacks and create quality_changes containers from the user containers.
|
||||||
|
stack_list = [global_stack] + list(global_stack.extruders.values())
|
||||||
|
for stack in stack_list:
|
||||||
|
user_container = stack.userChanges
|
||||||
|
quality_container = stack.quality
|
||||||
|
quality_changes_container = stack.qualityChanges
|
||||||
|
if not quality_container or not quality_changes_container:
|
||||||
|
Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
|
||||||
|
continue
|
||||||
|
|
||||||
|
extruder_definition_id = None
|
||||||
|
if isinstance(stack, ExtruderStack):
|
||||||
|
extruder_definition_id = stack.definition.getId()
|
||||||
|
quality_type = quality_container.getMetaDataEntry("quality_type")
|
||||||
|
new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_definition_id)
|
||||||
|
from cura.Settings.ContainerManager import ContainerManager
|
||||||
|
ContainerManager.getInstance()._performMerge(new_changes, quality_changes_container, clear_settings = False)
|
||||||
|
ContainerManager.getInstance()._performMerge(new_changes, user_container)
|
||||||
|
|
||||||
|
self._container_registry.addContainer(new_changes)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Create a quality changes container with the given setup.
|
||||||
|
#
|
||||||
|
def _createQualityChanges(self, quality_type: str, new_name: str, machine: "GlobalStack",
|
||||||
|
extruder_id: Optional[str]) -> "InstanceContainer":
|
||||||
|
base_id = machine.definition.getId() if extruder_id is None else extruder_id
|
||||||
|
new_id = base_id + "_" + new_name
|
||||||
|
new_id = new_id.lower().replace(" ", "_")
|
||||||
|
new_id = self._container_registry.uniqueName(new_id)
|
||||||
|
|
||||||
|
# Create a new quality_changes container for the quality.
|
||||||
|
quality_changes = InstanceContainer(new_id)
|
||||||
|
quality_changes.setName(new_name)
|
||||||
|
quality_changes.addMetaDataEntry("type", "quality_changes")
|
||||||
|
quality_changes.addMetaDataEntry("quality_type", quality_type)
|
||||||
|
|
||||||
|
# If we are creating a container for an extruder, ensure we add that to the container
|
||||||
|
if extruder_id is not None:
|
||||||
|
quality_changes.addMetaDataEntry("extruder", extruder_id)
|
||||||
|
|
||||||
|
# If the machine specifies qualities should be filtered, ensure we match the current criteria.
|
||||||
|
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
||||||
|
quality_changes.setDefinition(machine_definition_id)
|
||||||
|
|
||||||
|
quality_changes.addMetaDataEntry("setting_version", self._application.SettingVersion)
|
||||||
|
return quality_changes
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given
|
# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given
|
||||||
|
|
35
cura/Machines/QualityNode.py
Normal file
35
cura/Machines/QualityNode.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from .ContainerNode import ContainerNode
|
||||||
|
from .QualityChangesGroup import QualityChangesGroup
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# QualityNode is used for BOTH quality and quality_changes containers.
|
||||||
|
#
|
||||||
|
class QualityNode(ContainerNode):
|
||||||
|
|
||||||
|
def __init__(self, metadata: Optional[dict] = None):
|
||||||
|
super().__init__(metadata = metadata)
|
||||||
|
self.quality_type_map = {} # quality_type -> QualityNode for InstanceContainer
|
||||||
|
|
||||||
|
def addQualityMetadata(self, quality_type: str, metadata: dict):
|
||||||
|
if quality_type not in self.quality_type_map:
|
||||||
|
self.quality_type_map[quality_type] = QualityNode(metadata)
|
||||||
|
|
||||||
|
def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]:
|
||||||
|
return self.quality_type_map.get(quality_type)
|
||||||
|
|
||||||
|
def addQualityChangesMetadata(self, quality_type: str, metadata: dict):
|
||||||
|
if quality_type not in self.quality_type_map:
|
||||||
|
self.quality_type_map[quality_type] = QualityNode()
|
||||||
|
quality_type_node = self.quality_type_map[quality_type]
|
||||||
|
|
||||||
|
name = metadata["name"]
|
||||||
|
if name not in quality_type_node.children_map:
|
||||||
|
quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type)
|
||||||
|
quality_changes_group = quality_type_node.children_map[name]
|
||||||
|
quality_changes_group.addNode(QualityNode(metadata))
|
|
@ -1,17 +1,22 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import Optional
|
from typing import Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
from UM.Util import parseBool
|
||||||
|
|
||||||
from cura.Machines.ContainerNode import ContainerNode
|
from cura.Machines.ContainerNode import ContainerNode
|
||||||
from cura.Settings.GlobalStack import GlobalStack
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||||
|
|
||||||
class VariantType:
|
|
||||||
|
class VariantType(Enum):
|
||||||
BUILD_PLATE = "buildplate"
|
BUILD_PLATE = "buildplate"
|
||||||
NOZZLE = "nozzle"
|
NOZZLE = "nozzle"
|
||||||
|
|
||||||
|
@ -64,6 +69,7 @@ class VariantManager:
|
||||||
self._machine_to_variant_dict_map[variant_definition][variant_type] = dict()
|
self._machine_to_variant_dict_map[variant_definition][variant_type] = dict()
|
||||||
|
|
||||||
variant_type = variant_metadata["hardware_type"]
|
variant_type = variant_metadata["hardware_type"]
|
||||||
|
variant_type = VariantType(variant_type)
|
||||||
variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type]
|
variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type]
|
||||||
if variant_name in variant_dict:
|
if variant_name in variant_dict:
|
||||||
# ERROR: duplicated variant name.
|
# ERROR: duplicated variant name.
|
||||||
|
@ -77,10 +83,29 @@ class VariantManager:
|
||||||
# Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present.
|
# Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present.
|
||||||
#
|
#
|
||||||
def getVariantNode(self, machine_definition_id: str, variant_name: str,
|
def getVariantNode(self, machine_definition_id: str, variant_name: str,
|
||||||
variant_type: Optional[str] = VariantType.NOZZLE) -> Optional["ContainerNode"]:
|
variant_type: Optional["VariantType"] = VariantType.NOZZLE) -> Optional["ContainerNode"]:
|
||||||
return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}).get(variant_name)
|
return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}).get(variant_name)
|
||||||
|
|
||||||
def getVariantNodes(self, machine: "GlobalStack",
|
def getVariantNodes(self, machine: "GlobalStack",
|
||||||
variant_type: Optional[str] = VariantType.NOZZLE) -> dict:
|
variant_type: Optional["VariantType"] = VariantType.NOZZLE) -> dict:
|
||||||
machine_definition_id = machine.definition.getId()
|
machine_definition_id = machine.definition.getId()
|
||||||
return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {})
|
return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {})
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gets the default variant for the given machine definition.
|
||||||
|
#
|
||||||
|
def getDefaultVariantNode(self, machine_definition: "DefinitionContainer",
|
||||||
|
variant_type: VariantType) -> Optional["ContainerNode"]:
|
||||||
|
machine_definition_id = machine_definition.getId()
|
||||||
|
preferred_variant_name = None
|
||||||
|
if variant_type == VariantType.BUILD_PLATE:
|
||||||
|
if parseBool(machine_definition.getMetaDataEntry("has_variant_buildplates", False)):
|
||||||
|
preferred_variant_name = machine_definition.getMetaDataEntry("preferred_variant_buildplate_name")
|
||||||
|
else:
|
||||||
|
if parseBool(machine_definition.getMetaDataEntry("has_variants", False)):
|
||||||
|
preferred_variant_name = machine_definition.getMetaDataEntry("preferred_variant_name")
|
||||||
|
|
||||||
|
node = None
|
||||||
|
if preferred_variant_name:
|
||||||
|
node = self.getVariantNode(machine_definition_id, preferred_variant_name, variant_type)
|
||||||
|
return node
|
||||||
|
|
|
@ -202,8 +202,6 @@ class PrintInformation(QObject):
|
||||||
if global_stack is None:
|
if global_stack is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Material amount is sent as an amount of mm^3, so calculate length from that
|
|
||||||
radius = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2
|
|
||||||
self._material_lengths[build_plate_number] = []
|
self._material_lengths[build_plate_number] = []
|
||||||
self._material_weights[build_plate_number] = []
|
self._material_weights[build_plate_number] = []
|
||||||
self._material_costs[build_plate_number] = []
|
self._material_costs[build_plate_number] = []
|
||||||
|
@ -212,16 +210,16 @@ class PrintInformation(QObject):
|
||||||
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
|
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
|
||||||
|
|
||||||
extruder_stacks = global_stack.extruders
|
extruder_stacks = global_stack.extruders
|
||||||
for extruder_key in global_stack.extruders.keys():
|
for position, extruder_stack in extruder_stacks.items():
|
||||||
index = int(extruder_key)
|
index = int(position)
|
||||||
if index >= len(self._material_amounts): # Right now the _material_amounts is a list, where the index is the extruder number
|
if index >= len(self._material_amounts):
|
||||||
continue
|
continue
|
||||||
amount = self._material_amounts[index]
|
amount = self._material_amounts[index]
|
||||||
## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some
|
## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some
|
||||||
# list comprehension filtering to solve this for us.
|
# list comprehension filtering to solve this for us.
|
||||||
extruder_stack = extruder_stacks[str(index)]
|
|
||||||
density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0)
|
density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0)
|
||||||
material = extruder_stack.findContainer({"type": "material"})
|
material = extruder_stack.findContainer({"type": "material"})
|
||||||
|
radius = extruder_stack.getProperty("material_diameter", "value") / 2
|
||||||
|
|
||||||
weight = float(amount) * float(density) / 1000
|
weight = float(amount) * float(density) / 1000
|
||||||
cost = 0
|
cost = 0
|
||||||
|
@ -240,6 +238,7 @@ class PrintInformation(QObject):
|
||||||
else:
|
else:
|
||||||
cost = 0
|
cost = 0
|
||||||
|
|
||||||
|
# Material amount is sent as an amount of mm^3, so calculate length from that
|
||||||
if radius != 0:
|
if radius != 0:
|
||||||
length = round((amount / (math.pi * radius ** 2)) / 1000, 2)
|
length = round((amount / (math.pi * radius ** 2)) / 1000, 2)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -4,7 +4,7 @@ from PyQt5.QtCore import Qt, pyqtSlot, QObject
|
||||||
from PyQt5.QtWidgets import QApplication
|
from PyQt5.QtWidgets import QApplication
|
||||||
|
|
||||||
from cura.ObjectsModel import ObjectsModel
|
from cura.ObjectsModel import ObjectsModel
|
||||||
from cura.Machines.Models.Other.MultiBuildPlateModel import MultiBuildPlateModel
|
from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import copy
|
|
||||||
import os.path
|
import os.path
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import uuid
|
import uuid
|
||||||
|
@ -29,10 +28,10 @@ from UM.i18n import i18nCatalog
|
||||||
|
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
from cura.Settings.ExtruderStack import ExtruderStack
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
|
||||||
|
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
## Manager class that contains common actions to deal with containers in Cura.
|
## Manager class that contains common actions to deal with containers in Cura.
|
||||||
#
|
#
|
||||||
# This is primarily intended as a class to be able to perform certain actions
|
# This is primarily intended as a class to be able to perform certain actions
|
||||||
|
@ -160,17 +159,6 @@ class ContainerManager(QObject):
|
||||||
|
|
||||||
return container.getProperty(setting_key, property_name)
|
return container.getProperty(setting_key, property_name)
|
||||||
|
|
||||||
## Set the name of the specified material.
|
|
||||||
@pyqtSlot("QVariant", str)
|
|
||||||
def setMaterialName(self, material_node, new_name):
|
|
||||||
root_material_id = material_node.metadata["base_file"]
|
|
||||||
if self._container_registry.isReadOnly(root_material_id):
|
|
||||||
Logger.log("w", "Cannot set name of read-only container %s.", root_material_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
material_group = self._material_manager.getMaterialGroup(root_material_id)
|
|
||||||
material_group.root_material_node.getContainer().setName(new_name)
|
|
||||||
|
|
||||||
@pyqtSlot(str, result = str)
|
@pyqtSlot(str, result = str)
|
||||||
def makeUniqueName(self, original_name):
|
def makeUniqueName(self, original_name):
|
||||||
return self._container_registry.uniqueName(original_name)
|
return self._container_registry.uniqueName(original_name)
|
||||||
|
@ -355,191 +343,6 @@ class ContainerManager(QObject):
|
||||||
for container in send_emits_containers:
|
for container in send_emits_containers:
|
||||||
container.sendPostponedEmits()
|
container.sendPostponedEmits()
|
||||||
|
|
||||||
## Create quality changes containers from the user containers in the active stacks.
|
|
||||||
#
|
|
||||||
# This will go through the global and extruder stacks and create quality_changes containers from
|
|
||||||
# the user containers in each stack. These then replace the quality_changes containers in the
|
|
||||||
# stack and clear the user settings.
|
|
||||||
#
|
|
||||||
# \return \type{bool} True if the operation was successfully, False if not.
|
|
||||||
@pyqtSlot(str)
|
|
||||||
def createQualityChanges(self, base_name):
|
|
||||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
|
||||||
if not global_stack:
|
|
||||||
return
|
|
||||||
|
|
||||||
active_quality_name = self._machine_manager.activeQualityOrQualityChangesName
|
|
||||||
if active_quality_name == "":
|
|
||||||
Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
|
|
||||||
return
|
|
||||||
|
|
||||||
self._machine_manager.blurSettings.emit()
|
|
||||||
if base_name is None or base_name == "":
|
|
||||||
base_name = active_quality_name
|
|
||||||
unique_name = self._container_registry.uniqueName(base_name)
|
|
||||||
|
|
||||||
# Go through the active stacks and create quality_changes containers from the user containers.
|
|
||||||
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
|
||||||
user_container = stack.userChanges
|
|
||||||
quality_container = stack.quality
|
|
||||||
quality_changes_container = stack.qualityChanges
|
|
||||||
if not quality_container or not quality_changes_container:
|
|
||||||
Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
|
|
||||||
continue
|
|
||||||
|
|
||||||
extruder_definition_id = None
|
|
||||||
if isinstance(stack, ExtruderStack):
|
|
||||||
extruder_definition_id = stack.definition.getId()
|
|
||||||
quality_type = quality_container.getMetaDataEntry("quality_type")
|
|
||||||
new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_definition_id)
|
|
||||||
self._performMerge(new_changes, quality_changes_container, clear_settings = False)
|
|
||||||
self._performMerge(new_changes, user_container)
|
|
||||||
|
|
||||||
self._container_registry.addContainer(new_changes)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Remove the given quality changes group
|
|
||||||
#
|
|
||||||
@pyqtSlot(QObject)
|
|
||||||
def removeQualityChangesGroup(self, quality_changes_group):
|
|
||||||
Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name)
|
|
||||||
for node in quality_changes_group.getAllNodes():
|
|
||||||
self._container_registry.removeContainer(node.metadata["id"])
|
|
||||||
|
|
||||||
#
|
|
||||||
# Rename a set of quality changes containers. Returns the new name.
|
|
||||||
#
|
|
||||||
@pyqtSlot(QObject, str, result = str)
|
|
||||||
def renameQualityChangesGroup(self, quality_changes_group, new_name) -> str:
|
|
||||||
Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name)
|
|
||||||
self._machine_manager.blurSettings.emit()
|
|
||||||
|
|
||||||
if new_name == quality_changes_group.name:
|
|
||||||
Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name)
|
|
||||||
return new_name
|
|
||||||
|
|
||||||
new_name = self._container_registry.uniqueName(new_name)
|
|
||||||
for node in quality_changes_group.getAllNodes():
|
|
||||||
node.getContainer().setName(new_name)
|
|
||||||
|
|
||||||
self._machine_manager.activeQualityChanged.emit()
|
|
||||||
self._machine_manager.activeQualityGroupChanged.emit()
|
|
||||||
|
|
||||||
return new_name
|
|
||||||
|
|
||||||
@pyqtSlot(str, "QVariantMap")
|
|
||||||
def duplicateQualityChanges(self, quality_changes_name, quality_model_item):
|
|
||||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
|
||||||
|
|
||||||
quality_group = quality_model_item["quality_group"]
|
|
||||||
quality_changes_group = quality_model_item["quality_changes_group"]
|
|
||||||
if quality_changes_group is None:
|
|
||||||
# create global quality changes only
|
|
||||||
new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name,
|
|
||||||
global_stack, extruder_id = None)
|
|
||||||
self._container_registry.addContainer(new_quality_changes)
|
|
||||||
else:
|
|
||||||
new_name = self._container_registry.uniqueName(quality_changes_name)
|
|
||||||
for node in quality_changes_group.getAllNodes():
|
|
||||||
container = node.getContainer()
|
|
||||||
new_id = self._container_registry.uniqueName(container.getId())
|
|
||||||
self._container_registry.addContainer(container.duplicate(new_id, new_name))
|
|
||||||
|
|
||||||
@pyqtSlot("QVariant")
|
|
||||||
def removeMaterial(self, material_node):
|
|
||||||
root_material_id = material_node.metadata["base_file"]
|
|
||||||
material_group = self._material_manager.getMaterialGroup(root_material_id)
|
|
||||||
if not material_group:
|
|
||||||
Logger.log("d", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list
|
|
||||||
for node in nodes_to_remove:
|
|
||||||
self._container_registry.removeContainer(node.metadata["id"])
|
|
||||||
|
|
||||||
|
|
||||||
## Create a duplicate of a material, which has the same GUID and base_file metadata
|
|
||||||
#
|
|
||||||
# \return \type{str} the id of the newly created container.
|
|
||||||
@pyqtSlot("QVariant", result = str)
|
|
||||||
def duplicateMaterial(self, material_node, new_base_id = None, new_metadata = None):
|
|
||||||
root_material_id = material_node.metadata["base_file"]
|
|
||||||
|
|
||||||
material_group = self._material_manager.getMaterialGroup(root_material_id)
|
|
||||||
if not material_group:
|
|
||||||
Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
# Create a new ID & container to hold the data.
|
|
||||||
new_containers = []
|
|
||||||
if new_base_id is None:
|
|
||||||
new_base_id = self._container_registry.uniqueName(base_container.getId())
|
|
||||||
new_base_container = copy.deepcopy(base_container)
|
|
||||||
new_base_container.getMetaData()["id"] = new_base_id
|
|
||||||
new_base_container.getMetaData()["base_file"] = new_base_id
|
|
||||||
if new_metadata is not None:
|
|
||||||
for key, value in new_metadata.items():
|
|
||||||
new_base_container.getMetaData()[key] = value
|
|
||||||
new_containers.append(new_base_container)
|
|
||||||
|
|
||||||
# Clone all of them.
|
|
||||||
for container_to_copy in containers_to_copy:
|
|
||||||
# Create unique IDs for every clone.
|
|
||||||
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_name"):
|
|
||||||
variant_name = container_to_copy.getMetaDataEntry("variant_name")
|
|
||||||
new_id += "_" + variant_name.replace(" ", "_")
|
|
||||||
|
|
||||||
new_container = copy.deepcopy(container_to_copy)
|
|
||||||
new_container.getMetaData()["id"] = new_id
|
|
||||||
new_container.getMetaData()["base_file"] = new_base_id
|
|
||||||
if new_metadata is not None:
|
|
||||||
for key, value in new_metadata.items():
|
|
||||||
new_container.getMetaData()[key] = value
|
|
||||||
|
|
||||||
new_containers.append(new_container)
|
|
||||||
|
|
||||||
for container_to_add in new_containers:
|
|
||||||
container_to_add.setDirty(True)
|
|
||||||
ContainerRegistry.getInstance().addContainer(container_to_add)
|
|
||||||
return new_base_id
|
|
||||||
|
|
||||||
## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue
|
|
||||||
#
|
|
||||||
# \return \type{str} the id of the newly created container.
|
|
||||||
@pyqtSlot(result = str)
|
|
||||||
def createMaterial(self):
|
|
||||||
# Ensure all settings are saved.
|
|
||||||
Application.getInstance().saveSettings()
|
|
||||||
|
|
||||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
|
||||||
approximate_diameter = str(round(global_stack.getProperty("material_diameter", "value")))
|
|
||||||
root_material_id = "generic_pla"
|
|
||||||
root_material_id = self._material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_diameter)
|
|
||||||
material_group = self._material_manager.getMaterialGroup(root_material_id)
|
|
||||||
|
|
||||||
# Create a new ID & container to hold the data.
|
|
||||||
new_id = self._container_registry.uniqueName("custom_material")
|
|
||||||
new_metadata = {"name": catalog.i18nc("@label", "Custom Material"),
|
|
||||||
"brand": catalog.i18nc("@label", "Custom"),
|
|
||||||
"GUID": str(uuid.uuid4()),
|
|
||||||
}
|
|
||||||
|
|
||||||
self.duplicateMaterial(material_group.root_material_node,
|
|
||||||
new_base_id = new_id,
|
|
||||||
new_metadata = new_metadata)
|
|
||||||
return new_id
|
|
||||||
|
|
||||||
## Get a list of materials that have the same GUID as the reference material
|
## Get a list of materials that have the same GUID as the reference material
|
||||||
#
|
#
|
||||||
# \param material_id \type{str} the id of the material for which to get the linked materials.
|
# \param material_id \type{str} the id of the material for which to get the linked materials.
|
||||||
|
@ -643,51 +446,6 @@ class ContainerManager(QObject):
|
||||||
name_filter = "{0} ({1})".format(mime_type.comment, suffix_list)
|
name_filter = "{0} ({1})".format(mime_type.comment, suffix_list)
|
||||||
self._container_name_filters[name_filter] = entry
|
self._container_name_filters[name_filter] = entry
|
||||||
|
|
||||||
## Creates a unique ID for a container by prefixing the name with the stack ID.
|
|
||||||
#
|
|
||||||
# This method creates a unique ID for a container by prefixing it with a specified stack ID.
|
|
||||||
# This is done to ensure we have an easily identified ID for quality changes, which have the
|
|
||||||
# same name across several stacks.
|
|
||||||
#
|
|
||||||
# \param stack_id The ID of the stack to prepend.
|
|
||||||
# \param container_name The name of the container that we are creating a unique ID for.
|
|
||||||
#
|
|
||||||
# \return Container name prefixed with stack ID, in lower case with spaces replaced by underscores.
|
|
||||||
def _createUniqueId(self, stack_id, container_name):
|
|
||||||
result = stack_id + "_" + container_name
|
|
||||||
result = result.lower()
|
|
||||||
result.replace(" ", "_")
|
|
||||||
return result
|
|
||||||
|
|
||||||
## Create a quality changes container for a specified quality container.
|
|
||||||
#
|
|
||||||
# \param quality_container The quality container to create a changes container for.
|
|
||||||
# \param new_name The name of the new quality_changes container.
|
|
||||||
# \param machine_definition The machine definition this quality changes container is specific to.
|
|
||||||
# \param extruder_id
|
|
||||||
#
|
|
||||||
# \return A new quality_changes container with the specified container as base.
|
|
||||||
def _createQualityChanges(self, quality_type, new_name, machine, extruder_id):
|
|
||||||
base_id = machine.definition.getId() if extruder_id is None else extruder_id
|
|
||||||
|
|
||||||
# Create a new quality_changes container for the quality.
|
|
||||||
quality_changes = InstanceContainer(self._createUniqueId(base_id, new_name))
|
|
||||||
quality_changes.setName(new_name)
|
|
||||||
quality_changes.addMetaDataEntry("type", "quality_changes")
|
|
||||||
quality_changes.addMetaDataEntry("quality_type", quality_type)
|
|
||||||
|
|
||||||
# If we are creating a container for an extruder, ensure we add that to the container
|
|
||||||
if extruder_id is not None:
|
|
||||||
quality_changes.addMetaDataEntry("extruder", extruder_id)
|
|
||||||
|
|
||||||
# If the machine specifies qualities should be filtered, ensure we match the current criteria.
|
|
||||||
machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
|
|
||||||
quality_changes.setDefinition(machine_definition_id)
|
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
|
||||||
quality_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
|
||||||
return quality_changes
|
|
||||||
|
|
||||||
## Import single profile, file_url does not have to end with curaprofile
|
## Import single profile, file_url does not have to end with curaprofile
|
||||||
@pyqtSlot(QUrl, result="QVariantMap")
|
@pyqtSlot(QUrl, result="QVariantMap")
|
||||||
def importProfile(self, file_url):
|
def importProfile(self, file_url):
|
||||||
|
|
|
@ -41,29 +41,17 @@ class CuraStackBuilder:
|
||||||
|
|
||||||
# get variant container for the global stack
|
# get variant container for the global stack
|
||||||
global_variant_container = application.empty_variant_container
|
global_variant_container = application.empty_variant_container
|
||||||
if parseBool(machine_definition.getMetaDataEntry("has_variant_buildplates", False)):
|
global_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.BUILD_PLATE)
|
||||||
global_variant_name = machine_definition.getMetaDataEntry("preferred_variant_buildplate_name")
|
if global_variant_node:
|
||||||
if global_variant_name:
|
global_variant_container = global_variant_node.getContainer()
|
||||||
variant_node = variant_manager.getVariantNode(definition_id, global_variant_name,
|
|
||||||
variant_type = VariantType.BUILD_PLATE)
|
|
||||||
if variant_node is None:
|
|
||||||
raise RuntimeError("Cannot find buildplate variant with definition [%s] and variant name [%s]" %
|
|
||||||
(definition_id, global_variant_name))
|
|
||||||
global_variant_container = variant_node.getContainer()
|
|
||||||
|
|
||||||
# get variant container for extruders
|
# get variant container for extruders
|
||||||
extruder_variant_container = application.empty_variant_container
|
extruder_variant_container = application.empty_variant_container
|
||||||
# Only look for the preferred variant if this machine has variants
|
extruder_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.NOZZLE)
|
||||||
extruder_variant_name = None
|
extruder_variant_name = None
|
||||||
if parseBool(machine_definition.getMetaDataEntry("has_variants", False)):
|
if extruder_variant_node:
|
||||||
extruder_variant_name = machine_definition.getMetaDataEntry("preferred_variant_name")
|
extruder_variant_container = extruder_variant_node.getContainer()
|
||||||
if extruder_variant_name:
|
extruder_variant_name = extruder_variant_container.getName()
|
||||||
variant_node = variant_manager.getVariantNode(definition_id, extruder_variant_name)
|
|
||||||
# Sanity check. If you see this error, the related definition files should be fixed.
|
|
||||||
if variant_node is None:
|
|
||||||
raise RuntimeError("Cannot find extruder variant with definition [%s] and variant name [%s]" %
|
|
||||||
(definition_id, extruder_variant_name))
|
|
||||||
extruder_variant_container = variant_node.getContainer()
|
|
||||||
|
|
||||||
generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName())
|
generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName())
|
||||||
# Make sure the new name does not collide with any definition or (quality) profile
|
# Make sure the new name does not collide with any definition or (quality) profile
|
||||||
|
@ -83,19 +71,8 @@ class CuraStackBuilder:
|
||||||
|
|
||||||
# get material container for extruders
|
# get material container for extruders
|
||||||
material_container = application.empty_material_container
|
material_container = application.empty_material_container
|
||||||
# Only look for the preferred material if this machine has materials
|
material_node = material_manager.getDefaultMaterial(new_global_stack, extruder_variant_name)
|
||||||
if parseBool(machine_definition.getMetaDataEntry("has_materials", False)):
|
if material_node:
|
||||||
material_diameter = machine_definition.getProperty("material_diameter", "value")
|
|
||||||
if isinstance(material_diameter, SettingFunction):
|
|
||||||
material_diameter = material_diameter(new_global_stack)
|
|
||||||
approximate_material_diameter = str(round(material_diameter))
|
|
||||||
root_material_id = machine_definition.getMetaDataEntry("preferred_material")
|
|
||||||
root_material_id = material_manager.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter)
|
|
||||||
material_node = material_manager.getMaterialNode(definition_id, extruder_variant_name, material_diameter, root_material_id)
|
|
||||||
# Sanity check. If you see this error, the related definition files should be fixed.
|
|
||||||
if not material_node:
|
|
||||||
raise RuntimeError("Cannot find material with definition [%s], extruder_variant_name [%s], and root_material_id [%s]" %
|
|
||||||
(definition_id, extruder_variant_name, root_material_id))
|
|
||||||
material_container = material_node.getContainer()
|
material_container = material_node.getContainer()
|
||||||
|
|
||||||
# Create ExtruderStacks
|
# Create ExtruderStacks
|
||||||
|
|
|
@ -414,6 +414,33 @@ class ExtruderManager(QObject):
|
||||||
self.extrudersChanged.emit(global_stack_id)
|
self.extrudersChanged.emit(global_stack_id)
|
||||||
self.setActiveExtruderIndex(0)
|
self.setActiveExtruderIndex(0)
|
||||||
|
|
||||||
|
#
|
||||||
|
# This function tries to fix the problem with per-extruder-settable nozzle size and material diameter problems
|
||||||
|
# in early versions (3.0 - 3.2.1).
|
||||||
|
#
|
||||||
|
# In earlier versions, "nozzle size" and "material diameter" are only applicable to the complete machine, so all
|
||||||
|
# extruders share the same values. In this case, "nozzle size" and "material diameter" are saved in the
|
||||||
|
# GlobalStack's DefinitionChanges container.
|
||||||
|
#
|
||||||
|
# Later, we could have different "nozzle size" for each extruder, but "material diameter" could only be set for
|
||||||
|
# the entire machine. In this case, "nozzle size" should be saved in each ExtruderStack's DefinitionChanges, but
|
||||||
|
# "material diameter" still remains in the GlobalStack's DefinitionChanges.
|
||||||
|
#
|
||||||
|
# Lateer, both "nozzle size" and "material diameter" are settable per-extruder, and both settings should be saved
|
||||||
|
# in the ExtruderStack's DefinitionChanges.
|
||||||
|
#
|
||||||
|
# There were some bugs in upgrade so the data weren't saved correct as described above. This function tries fix
|
||||||
|
# this.
|
||||||
|
#
|
||||||
|
# One more thing is about material diameter and single-extrusion machines. Most single-extrusion machines don't
|
||||||
|
# specifically define their extruder definition, so they reuse "fdmextruder", but for those machines, they may
|
||||||
|
# define "material diameter = 1.75" in their machine definition, but in "fdmextruder", it's still "2.85". This
|
||||||
|
# causes a problem with incorrect default values.
|
||||||
|
#
|
||||||
|
# This is also fixed here in this way: If no "material diameter" is specified, it will look for the default value
|
||||||
|
# in both the Extruder's definition and the Global's definition. If 2 values don't match, we will use the value
|
||||||
|
# from the Global definition by setting it in the Extruder's DefinitionChanges container.
|
||||||
|
#
|
||||||
def _fixMaterialDiameterAndNozzleSize(self, global_stack, extruder_stack_list):
|
def _fixMaterialDiameterAndNozzleSize(self, global_stack, extruder_stack_list):
|
||||||
keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders
|
keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders
|
||||||
|
|
||||||
|
@ -424,22 +451,6 @@ class ExtruderManager(QObject):
|
||||||
if extruder_stack.definitionChanges.hasProperty(key, "value"):
|
if extruder_stack.definitionChanges.hasProperty(key, "value"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
#
|
|
||||||
# We cannot add a setting definition of "material_diameter" into the extruder's definition at runtime
|
|
||||||
# because all other machines which uses "fdmextruder" as the extruder definition will be affected.
|
|
||||||
#
|
|
||||||
# The problem is that single extrusion machines have their default material diameter defined in the global
|
|
||||||
# definitions. Now we automatically create an extruder stack for those machines using "fdmextruder"
|
|
||||||
# definition, which doesn't have the specific "material_diameter" and "machine_nozzle_size" defined for
|
|
||||||
# each machine. This results in wrong values which can be found in the MachineSettings dialog.
|
|
||||||
#
|
|
||||||
# To solve this, we put "material_diameter" back into the "fdmextruder" definition because modifying it in
|
|
||||||
# the extruder definition will affect all machines which uses the "fdmextruder" definition. Moreover, now
|
|
||||||
# we also check the value defined in the machine definition. If present, the value defined in the global
|
|
||||||
# stack's definition changes container will be copied. Otherwise, we will check if the default values in the
|
|
||||||
# machine definition and the extruder definition are the same, and if not, the default value in the machine
|
|
||||||
# definition will be copied to the extruder stack's definition changes.
|
|
||||||
#
|
|
||||||
setting_value_in_global_def_changes = global_stack.definitionChanges.getProperty(key, "value")
|
setting_value_in_global_def_changes = global_stack.definitionChanges.getProperty(key, "value")
|
||||||
setting_value_in_global_def = global_stack.definition.getProperty(key, "value")
|
setting_value_in_global_def = global_stack.definition.getProperty(key, "value")
|
||||||
setting_value = setting_value_in_global_def
|
setting_value = setting_value_in_global_def
|
||||||
|
|
|
@ -13,7 +13,7 @@ from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext
|
||||||
from UM.Util import parseBool
|
from UM.Util import parseBool
|
||||||
|
|
||||||
from . import Exceptions
|
from . import Exceptions
|
||||||
from .CuraContainerStack import CuraContainerStack
|
from .CuraContainerStack import CuraContainerStack, _ContainerIndexes
|
||||||
from .ExtruderManager import ExtruderManager
|
from .ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
@ -69,14 +69,10 @@ class ExtruderStack(CuraContainerStack):
|
||||||
# \return The filament diameter for the printer
|
# \return The filament diameter for the printer
|
||||||
@property
|
@property
|
||||||
def materialDiameter(self) -> float:
|
def materialDiameter(self) -> float:
|
||||||
containers_to_check = [self.variant, self.definitionChanges, self.definition]
|
context = PropertyEvaluationContext(self)
|
||||||
|
context.context["evaluate_from_container_index"] = _ContainerIndexes.Variant
|
||||||
|
|
||||||
for container in containers_to_check:
|
return self.getProperty("material_diameter", "value", context = context)
|
||||||
if container is not None:
|
|
||||||
material_diameter = container.getProperty("material_diameter", "value")
|
|
||||||
if material_diameter is not None:
|
|
||||||
return material_diameter
|
|
||||||
return -1
|
|
||||||
|
|
||||||
## Return the approximate filament diameter that the machine requires.
|
## Return the approximate filament diameter that the machine requires.
|
||||||
#
|
#
|
||||||
|
|
|
@ -119,16 +119,13 @@ class MachineManager(QObject):
|
||||||
if containers:
|
if containers:
|
||||||
containers[0].nameChanged.connect(self._onMaterialNameChanged)
|
containers[0].nameChanged.connect(self._onMaterialNameChanged)
|
||||||
|
|
||||||
# NEW
|
|
||||||
self._material_manager = self._application._material_manager
|
self._material_manager = self._application._material_manager
|
||||||
self._material_manager.materialsUpdated.connect(self._onMaterialsUpdated)
|
self._quality_manager = self._application.getQualityManager()
|
||||||
|
|
||||||
def _onMaterialsUpdated(self):
|
|
||||||
# When the materials lookup table gets updated, it can mean that a material has its name changed, which should
|
# When the materials lookup table gets updated, it can mean that a material has its name changed, which should
|
||||||
# be reflected on the GUI. This signal emission makes sure that it happens.
|
# be reflected on the GUI. This signal emission makes sure that it happens.
|
||||||
self.rootMaterialChanged.emit()
|
self._material_manager.materialsUpdated.connect(self.rootMaterialChanged)
|
||||||
|
|
||||||
### NEW
|
|
||||||
activeQualityGroupChanged = pyqtSignal()
|
activeQualityGroupChanged = pyqtSignal()
|
||||||
activeQualityChangesGroupChanged = pyqtSignal()
|
activeQualityChangesGroupChanged = pyqtSignal()
|
||||||
|
|
||||||
|
@ -303,14 +300,12 @@ class MachineManager(QObject):
|
||||||
if containers:
|
if containers:
|
||||||
global_stack = containers[0]
|
global_stack = containers[0]
|
||||||
ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder
|
ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder
|
||||||
Application.getInstance().setGlobalContainerStack(global_stack)
|
|
||||||
self._global_container_stack = global_stack
|
self._global_container_stack = global_stack
|
||||||
Application.getInstance().setGlobalContainerStack(global_stack)
|
Application.getInstance().setGlobalContainerStack(global_stack)
|
||||||
ExtruderManager.getInstance()._globalContainerStackChanged()
|
ExtruderManager.getInstance()._globalContainerStackChanged()
|
||||||
self._initMachineState(containers[0])
|
self._initMachineState(containers[0])
|
||||||
self.updateDefaultExtruder()
|
self.updateDefaultExtruder()
|
||||||
self.updateNumberExtrudersEnabled()
|
self.updateNumberExtrudersEnabled()
|
||||||
self.globalContainerChanged.emit()
|
|
||||||
self._onGlobalContainerChanged()
|
self._onGlobalContainerChanged()
|
||||||
|
|
||||||
self.__emitChangedSignals()
|
self.__emitChangedSignals()
|
||||||
|
@ -835,11 +830,6 @@ class MachineManager(QObject):
|
||||||
container = extruder.userChanges
|
container = extruder.userChanges
|
||||||
container.setProperty(setting_name, property_name, property_value)
|
container.setProperty(setting_name, property_name, property_value)
|
||||||
|
|
||||||
#
|
|
||||||
# New
|
|
||||||
#
|
|
||||||
|
|
||||||
# We not fetch it from _current_root_material_id, but later we can get it from somewhere else
|
|
||||||
@pyqtProperty("QVariantList", notify = rootMaterialChanged)
|
@pyqtProperty("QVariantList", notify = rootMaterialChanged)
|
||||||
def currentExtruderPositions(self):
|
def currentExtruderPositions(self):
|
||||||
return sorted(list(self._current_root_material_id.keys()))
|
return sorted(list(self._current_root_material_id.keys()))
|
||||||
|
@ -879,6 +869,10 @@ class MachineManager(QObject):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
#
|
||||||
|
# Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers
|
||||||
|
# for all stacks in the currently active machine.
|
||||||
|
#
|
||||||
def _setEmptyQuality(self):
|
def _setEmptyQuality(self):
|
||||||
self._current_quality_group = None
|
self._current_quality_group = None
|
||||||
self._current_quality_changes_group = None
|
self._current_quality_changes_group = None
|
||||||
|
@ -911,11 +905,8 @@ class MachineManager(QObject):
|
||||||
self.activeQualityChangesGroupChanged.emit()
|
self.activeQualityChangesGroupChanged.emit()
|
||||||
|
|
||||||
def _setQualityChangesGroup(self, quality_changes_group):
|
def _setQualityChangesGroup(self, quality_changes_group):
|
||||||
# TODO: quality_changes groups depend on a quality_type. Here it's fetching the quality_types every time.
|
|
||||||
# Can we do this better, like caching the quality group a quality_changes group depends on?
|
|
||||||
quality_type = quality_changes_group.quality_type
|
quality_type = quality_changes_group.quality_type
|
||||||
quality_manager = Application.getInstance()._quality_manager
|
quality_group_dict = self._quality_manager.getQualityGroups(self._global_container_stack)
|
||||||
quality_group_dict = quality_manager.getQualityGroups(self._global_container_stack)
|
|
||||||
quality_group = quality_group_dict[quality_type]
|
quality_group = quality_group_dict[quality_type]
|
||||||
|
|
||||||
quality_changes_container = self._empty_quality_changes_container
|
quality_changes_container = self._empty_quality_changes_container
|
||||||
|
@ -1031,13 +1022,6 @@ class MachineManager(QObject):
|
||||||
self._setMaterial(position, new_material)
|
self._setMaterial(position, new_material)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# # Find a fallback material
|
|
||||||
# preferred_material_query = self._global_container_stack.getMetaDataEntry("preferred_material")
|
|
||||||
# preferred_material_key = preferred_material_query.replace("*", "")
|
|
||||||
# if preferred_material_key in candidate_materials:
|
|
||||||
# self._setMaterial(position, candidate_materials[preferred_material_key])
|
|
||||||
# return
|
|
||||||
|
|
||||||
@pyqtSlot("QVariant")
|
@pyqtSlot("QVariant")
|
||||||
def setGlobalVariant(self, container_node):
|
def setGlobalVariant(self, container_node):
|
||||||
self.blurSettings.emit()
|
self.blurSettings.emit()
|
||||||
|
|
|
@ -3,12 +3,14 @@
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
|
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
|
||||||
from UM.Signal import Signal, signalemitter
|
from UM.Signal import Signal, signalemitter
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
|
from UM.Settings.Validator import ValidatorState
|
||||||
|
from PyQt5.QtCore import QTimer
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
|
||||||
from cura.Settings.PerObjectContainerStack import PerObjectContainerStack
|
from cura.Settings.PerObjectContainerStack import PerObjectContainerStack
|
||||||
|
@ -38,6 +40,10 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||||
|
|
||||||
self._is_non_printing_mesh = False
|
self._is_non_printing_mesh = False
|
||||||
|
self._error_check_timer = QTimer()
|
||||||
|
self._error_check_timer.setInterval(250)
|
||||||
|
self._error_check_timer.setSingleShot(True)
|
||||||
|
self._error_check_timer.timeout.connect(self._checkStackForErrors)
|
||||||
|
|
||||||
self._stack.propertyChanged.connect(self._onSettingChanged)
|
self._stack.propertyChanged.connect(self._onSettingChanged)
|
||||||
|
|
||||||
|
@ -97,8 +103,21 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||||
if property_name == "value":
|
if property_name == "value":
|
||||||
self._is_non_printing_mesh = self.evaluateIsNonPrintingMesh()
|
self._is_non_printing_mesh = self.evaluateIsNonPrintingMesh()
|
||||||
|
|
||||||
Application.getInstance().getBackend().needsSlicing()
|
if not self._is_non_printing_mesh:
|
||||||
Application.getInstance().getBackend().tickle()
|
# self._error_check_timer.start()
|
||||||
|
self._checkStackForErrors()
|
||||||
|
Application.getInstance().getBackend().needsSlicing()
|
||||||
|
Application.getInstance().getBackend().tickle()
|
||||||
|
|
||||||
|
def _checkStackForErrors(self):
|
||||||
|
hasErrors = False;
|
||||||
|
for key in self._stack.getAllKeys():
|
||||||
|
validation_state = self._stack.getProperty(key, "validationState")
|
||||||
|
if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError):
|
||||||
|
Logger.log("w", "Setting Per Object %s is not valid.", key)
|
||||||
|
hasErrors = True
|
||||||
|
break
|
||||||
|
Application.getInstance().getObjectsModel().setStacksHaveErrors(hasErrors)
|
||||||
|
|
||||||
## Makes sure that the stack upon which the container stack is placed is
|
## Makes sure that the stack upon which the container stack is placed is
|
||||||
# kept up to date.
|
# kept up to date.
|
||||||
|
|
|
@ -1082,6 +1082,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit()
|
CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit()
|
||||||
|
|
||||||
# Actually change the active machine.
|
# Actually change the active machine.
|
||||||
|
#
|
||||||
|
# This is scheduled for later is because it depends on the Variant/Material/Qualitiy Managers to have the latest
|
||||||
|
# data, but those managers will only update upon a container/container metadata changed signal. Because this
|
||||||
|
# function is running on the main thread (Qt thread), although those "changed" signals have been emitted, but
|
||||||
|
# they won't take effect until this function is done.
|
||||||
|
# To solve this, we schedule _updateActiveMachine() for later so it will have the latest data.
|
||||||
CuraApplication.getInstance().callLater(self._updateActiveMachine, global_stack)
|
CuraApplication.getInstance().callLater(self._updateActiveMachine, global_stack)
|
||||||
|
|
||||||
# Load all the nodes / meshdata of the workspace
|
# Load all the nodes / meshdata of the workspace
|
||||||
|
|
|
@ -32,11 +32,11 @@ UM.TooltipArea
|
||||||
if(checked)
|
if(checked)
|
||||||
{
|
{
|
||||||
addedSettingsModel.setVisible(model.key, checked);
|
addedSettingsModel.setVisible(model.key, checked);
|
||||||
UM.ActiveTool.triggerAction("subscribeForSettingValidation", model.key)
|
UM.ActiveTool.triggerActionWithData("subscribeForSettingValidation", model.key)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UM.ActiveTool.triggerAction("unsubscribeForSettingValidation", model.key)
|
UM.ActiveTool.triggerActionWithData("unsubscribeForSettingValidation", model.key)
|
||||||
addedSettingsModel.setVisible(model.key, checked);
|
addedSettingsModel.setVisible(model.key, checked);
|
||||||
}
|
}
|
||||||
UM.ActiveTool.forceUpdate();
|
UM.ActiveTool.forceUpdate();
|
||||||
|
|
|
@ -242,7 +242,7 @@ Item {
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
addedSettingsModel.setVisible(model.key, false)
|
addedSettingsModel.setVisible(model.key, false)
|
||||||
UM.ActiveTool.triggerAction("unsubscribeForSettingValidation", model.key)
|
UM.ActiveTool.triggerActionWithData("unsubscribeForSettingValidation", model.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
style: ButtonStyle
|
style: ButtonStyle
|
||||||
|
|
|
@ -44,7 +44,6 @@ class PerObjectSettingsTool(Tool):
|
||||||
self._error_check_timer.setSingleShot(True)
|
self._error_check_timer.setSingleShot(True)
|
||||||
self._error_check_timer.timeout.connect(self._updateStacksHaveErrors)
|
self._error_check_timer.timeout.connect(self._updateStacksHaveErrors)
|
||||||
|
|
||||||
|
|
||||||
def event(self, event):
|
def event(self, event):
|
||||||
super().event(event)
|
super().event(event)
|
||||||
if event.type == Event.MousePressEvent and self._controller.getToolsEnabled():
|
if event.type == Event.MousePressEvent and self._controller.getToolsEnabled():
|
||||||
|
@ -156,10 +155,12 @@ class PerObjectSettingsTool(Tool):
|
||||||
|
|
||||||
def _onPropertyChanged(self, key: str, property_name: str) -> None:
|
def _onPropertyChanged(self, key: str, property_name: str) -> None:
|
||||||
if property_name == "validationState":
|
if property_name == "validationState":
|
||||||
self._error_check_timer.start()
|
# self._error_check_timer.start()
|
||||||
|
return
|
||||||
|
|
||||||
def _updateStacksHaveErrors(self) -> None:
|
def _updateStacksHaveErrors(self) -> None:
|
||||||
self._checkStacksHaveErrors()
|
return
|
||||||
|
# self._checkStacksHaveErrors()
|
||||||
|
|
||||||
|
|
||||||
def _checkStacksHaveErrors(self):
|
def _checkStacksHaveErrors(self):
|
||||||
|
@ -180,6 +181,7 @@ class PerObjectSettingsTool(Tool):
|
||||||
|
|
||||||
|
|
||||||
def _checkStackForErrors(self, stack):
|
def _checkStackForErrors(self, stack):
|
||||||
|
print("checking for errors")
|
||||||
if stack is None:
|
if stack is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,12 @@ 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
|
||||||
|
#
|
||||||
|
# The "apply_to_all" flag indicates whether this piece of metadata should be applied to all material containers
|
||||||
|
# or just this specific container.
|
||||||
|
# For example, when you change the material name, you want to apply it to all its derived containers, but for
|
||||||
|
# some specific settings, they should only be applied to a machine/variant-specific container.
|
||||||
|
#
|
||||||
def setMetaDataEntry(self, key, value, apply_to_all = 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()):
|
||||||
|
@ -59,7 +65,7 @@ class XmlMaterialProfile(InstanceContainer):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the MaterialGroup
|
# Get the MaterialGroup
|
||||||
material_manager = CuraApplication.getInstance()._material_manager
|
material_manager = CuraApplication.getInstance().getMaterialManager()
|
||||||
root_material_id = self.getMetaDataEntry("base_file") #if basefile is self.getId, this is a basefile.
|
root_material_id = self.getMetaDataEntry("base_file") #if basefile is self.getId, this is a basefile.
|
||||||
material_group = material_manager.getMaterialGroup(root_material_id)
|
material_group = material_manager.getMaterialGroup(root_material_id)
|
||||||
|
|
||||||
|
@ -606,8 +612,6 @@ class XmlMaterialProfile(InstanceContainer):
|
||||||
if not variant_node:
|
if not variant_node:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# TODO: check if build plate variant exists
|
|
||||||
|
|
||||||
buildplate_compatibility = machine_compatibility
|
buildplate_compatibility = machine_compatibility
|
||||||
buildplate_recommended = machine_compatibility
|
buildplate_recommended = machine_compatibility
|
||||||
settings = buildplate.iterfind("./um:setting", self.__namespaces)
|
settings = buildplate.iterfind("./um:setting", self.__namespaces)
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"author": "ABAX 3d Technologies",
|
"author": "ABAX 3d Technologies",
|
||||||
"manufacturer": "ABAX 3d Technologies",
|
"manufacturer": "ABAX 3d Technologies",
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode"
|
||||||
"has_machine_quality": true
|
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"machine_start_gcode": {
|
"machine_start_gcode": {
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
"default_value": 60
|
"default_value": 60
|
||||||
},
|
},
|
||||||
"speed_travel": {
|
"speed_travel": {
|
||||||
"default_value": 100
|
"value": "100"
|
||||||
},
|
},
|
||||||
"retraction_amount": {
|
"retraction_amount": {
|
||||||
"default_value": 3.5
|
"default_value": 3.5
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
"default_value": "elliptic"
|
"default_value": "elliptic"
|
||||||
},
|
},
|
||||||
"machine_gcode_flavor": {
|
"machine_gcode_flavor": {
|
||||||
"default_value": "RepRap"
|
"default_value": "RepRap (RepRap)"
|
||||||
},
|
},
|
||||||
"machine_start_gcode": {
|
"machine_start_gcode": {
|
||||||
"default_value": ";Gcode by Cura\nG90\nG28\nM109 S100\nG29\nM104 S{material_print_temperature_layer_0}\nG0 X0 Y-85\nG0 Z0.26\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E6\nG92 E0\nG1 F200 E-3.5\nG0 Z0.15\nG0 X10\nG0 Z3\nG1 F6000\n"
|
"default_value": ";Gcode by Cura\nG90\nG28\nM109 S100\nG29\nM104 S{material_print_temperature_layer_0}\nG0 X0 Y-85\nG0 Z0.26\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E6\nG92 E0\nG1 F200 E-3.5\nG0 Z0.15\nG0 X10\nG0 Z3\nG1 F6000\n"
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"machine_name": { "default_value": "FABtotum Personal Fabricator" },
|
"machine_name": { "default_value": "FABtotum Personal Fabricator" },
|
||||||
"machine_start_gcode": {
|
"machine_start_gcode": {
|
||||||
"default_value": ";Layer height: {layer_height}\n;Walls: {wall_thickness}\n;Fill: {infill_sparse_density}\n;Top\\Bottom Thickness: {top_bottom_thickness}\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG4 S1 ;1 millisecond pause to buffer the bep bep \nM728 ;FAB bep bep (start the print, go check the oozing and skirt lines adesion) \nG4 S1 ;1 second pause to reach the printer (run fast)\nG92 E0 ;zero the extruded length \nG1 F200 E35 ;slowly extrude 35mm of filament to clean the nozzle and build up extrusion pressure \nG92 E0 ;zero the extruded length again \nG1 F{speed_travel} ;Set travel speed \n;print"
|
"default_value": ";Layer height: {layer_height}\n;Walls: {wall_thickness}\n;Fill: {infill_sparse_density}\n;Top\\Bottom Thickness: {top_bottom_thickness}\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG4 S1 ;1 millisecond pause to buffer the bep bep \nM300 S2 ;FAB bep bep (start the print, go check the oozing and skirt lines adesion) \nG4 S1 ;1 second pause to reach the printer (run fast)\nG92 E0 ;zero the extruded length \nG1 F200 E35 ;slowly extrude 35mm of filament to clean the nozzle and build up extrusion pressure \nG92 E0 ;zero the extruded length again \n;print"
|
||||||
},
|
},
|
||||||
"machine_end_gcode": {
|
"machine_end_gcode": {
|
||||||
"default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-3 X+5 Y+5 F5000 ;move Z up a bit and retract filament even more\n;end of the print\nM84 ;steppers off\nG90 ;absolute positioning\nM728 ;FAB bep bep (end print)"
|
"default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-3 X+5 Y+5 F5000 ;move Z up a bit and retract filament even more\n;end of the print\nM84 ;steppers off\nG90 ;absolute positioning\nM300 S2 ;FAB bep bep (end print)"
|
||||||
},
|
},
|
||||||
"gantry_height": { "default_value": 55 },
|
"gantry_height": { "default_value": 55 },
|
||||||
"machine_width": { "default_value": 214 },
|
"machine_width": { "default_value": 214 },
|
||||||
|
|
|
@ -20,12 +20,10 @@
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"machine_name": { "default_value": "Ultimaker 2" },
|
"machine_name": { "default_value": "Ultimaker 2" },
|
||||||
"machine_start_gcode" : {
|
"machine_start_gcode" : {
|
||||||
"default_value": "",
|
|
||||||
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nG28 Z0 ;move Z to bottom endstops\\nG28 X0 Y0 ;move X/Y to endstops\\nG1 X15 Y0 F4000 ;move X/Y to front of printer\\nG1 Z15.0 F9000 ;move the platform to 15mm\\nG92 E0 ;zero the extruded length\\nG1 F200 E10 ;extrude 10 mm of feed stock\\nG92 E0 ;zero the extruded length again\\nG1 F9000\\n;Put printing message on LCD screen\\nM117 Printing...\""
|
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nG28 Z0 ;move Z to bottom endstops\\nG28 X0 Y0 ;move X/Y to endstops\\nG1 X15 Y0 F4000 ;move X/Y to front of printer\\nG1 Z15.0 F9000 ;move the platform to 15mm\\nG92 E0 ;zero the extruded length\\nG1 F200 E10 ;extrude 10 mm of feed stock\\nG92 E0 ;zero the extruded length again\\nG1 F9000\\n;Put printing message on LCD screen\\nM117 Printing...\""
|
||||||
},
|
},
|
||||||
"machine_end_gcode" : {
|
"machine_end_gcode" : {
|
||||||
"default_value": "",
|
"value": "\";Version _2.6 of the firmware can abort the print too early if the file ends\\n;too soon. However if the file hasn't ended yet because there are comments at\\n;the end of the file, it won't abort yet. Therefore we have to put at least 512\\n;bytes at the end of the g-code so that the file is not yet finished by the\\n;time that the motion planner gets flushed. With firmware version _3.3 this\\n;should be fixed, so this comment wouldn't be necessary any more. Now we have\\n;to pad this text to make precisely 512 bytes.\" if machine_gcode_flavor == \"UltiGCode\" else \"M104 S0 ;extruder heater off\\nM140 S0 ;heated bed heater off (if you have it)\\nG91 ;relative positioning\\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\\nM84 ;steppers off\\nG90 ;absolute positioning\\n;Version _2.6 of the firmware can abort the print too early if the file ends\\n;too soon. However if the file hasn't ended yet because there are comments at\\n;the end of the file, it won't abort yet. Therefore we have to put at least 512\\n;bytes at the end of the g-code so that the file is not yet finished by the\\n;time that the motion planner gets flushed. With firmware version _3.3 this\\n;should be fixed, so this comment wouldn't be necessary any more. Now we have\\n;to pad this text to make precisely 512 bytes.\""
|
||||||
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"M104 S0 ;extruder heater off\\nM140 S0 ;heated bed heater off (if you have it)\\nG91 ;relative positioning\\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\\nM84 ;steppers off\\nG90 ;absolute positioning\""
|
|
||||||
},
|
},
|
||||||
"machine_width": {
|
"machine_width": {
|
||||||
"default_value": 223
|
"default_value": 223
|
||||||
|
|
|
@ -123,7 +123,6 @@
|
||||||
"raft_margin": { "value": "10" },
|
"raft_margin": { "value": "10" },
|
||||||
"raft_surface_layers": { "value": "1" },
|
"raft_surface_layers": { "value": "1" },
|
||||||
"retraction_amount": { "value": "2" },
|
"retraction_amount": { "value": "2" },
|
||||||
"retraction_combing": { "default_value": "noskin" },
|
|
||||||
"retraction_count_max": { "value": "10" },
|
"retraction_count_max": { "value": "10" },
|
||||||
"retraction_extrusion_window": { "value": "1" },
|
"retraction_extrusion_window": { "value": "1" },
|
||||||
"retraction_hop": { "value": "2" },
|
"retraction_hop": { "value": "2" },
|
||||||
|
@ -154,6 +153,7 @@
|
||||||
"travel_avoid_distance": { "value": "3" },
|
"travel_avoid_distance": { "value": "3" },
|
||||||
"wall_0_inset": { "value": "0" },
|
"wall_0_inset": { "value": "0" },
|
||||||
"wall_line_width_x": { "value": "round(wall_line_width * 0.3 / 0.35, 2)" },
|
"wall_line_width_x": { "value": "round(wall_line_width * 0.3 / 0.35, 2)" },
|
||||||
"wall_thickness": { "value": "1" }
|
"wall_thickness": { "value": "1" },
|
||||||
|
"zig_zaggify_infill": { "value": "True" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,120 +8,71 @@ weight = 2
|
||||||
layer_height
|
layer_height
|
||||||
layer_height_0
|
layer_height_0
|
||||||
line_width
|
line_width
|
||||||
|
wall_line_width
|
||||||
|
wall_line_width_0
|
||||||
|
wall_line_width_x
|
||||||
|
skin_line_width
|
||||||
|
infill_line_width
|
||||||
|
initial_layer_line_width_factor
|
||||||
|
|
||||||
[shell]
|
[shell]
|
||||||
wall_extruder_nr
|
wall_extruder_nr
|
||||||
|
wall_0_extruder_nr
|
||||||
|
wall_x_extruder_nr
|
||||||
wall_thickness
|
wall_thickness
|
||||||
wall_0_wipe_dist
|
wall_line_count
|
||||||
roofing_extruder_nr
|
|
||||||
roofing_layer_count
|
|
||||||
top_bottom_extruder_nr
|
top_bottom_extruder_nr
|
||||||
top_bottom_thickness
|
top_bottom_thickness
|
||||||
top_bottom_pattern
|
top_thickness
|
||||||
top_bottom_pattern_0
|
top_layers
|
||||||
skin_angles
|
bottom_thickness
|
||||||
wall_0_inset
|
bottom_layers
|
||||||
optimize_wall_printing_order
|
optimize_wall_printing_order
|
||||||
outer_inset_first
|
|
||||||
alternate_extra_perimeter
|
|
||||||
travel_compensate_overlapping_walls_enabled
|
|
||||||
fill_perimeter_gaps
|
fill_perimeter_gaps
|
||||||
filter_out_tiny_gaps
|
|
||||||
fill_outline_gaps
|
|
||||||
xy_offset
|
xy_offset
|
||||||
xy_offset_layer_0
|
|
||||||
z_seam_type
|
|
||||||
z_seam_x
|
|
||||||
z_seam_y
|
|
||||||
z_seam_corner
|
|
||||||
z_seam_relative
|
|
||||||
skin_no_small_gaps_heuristic
|
|
||||||
skin_outline_count
|
|
||||||
ironing_enabled
|
ironing_enabled
|
||||||
ironing_only_highest_layer
|
|
||||||
ironing_pattern
|
|
||||||
ironing_line_spacing
|
|
||||||
ironing_flow
|
|
||||||
ironing_inset
|
|
||||||
speed_ironing
|
|
||||||
acceleration_ironing
|
|
||||||
jerk_ironing
|
|
||||||
|
|
||||||
[infill]
|
[infill]
|
||||||
infill_extruder_nr
|
infill_extruder_nr
|
||||||
infill_sparse_density
|
infill_sparse_density
|
||||||
|
infill_line_distance
|
||||||
infill_pattern
|
infill_pattern
|
||||||
zig_zaggify_infill
|
|
||||||
infill_angles
|
|
||||||
infill_offset_x
|
|
||||||
infill_offset_y
|
|
||||||
sub_div_rad_add
|
|
||||||
infill_overlap
|
infill_overlap
|
||||||
skin_overlap
|
|
||||||
infill_wipe_dist
|
|
||||||
infill_sparse_thickness
|
infill_sparse_thickness
|
||||||
gradual_infill_steps
|
gradual_infill_steps
|
||||||
gradual_infill_step_height
|
|
||||||
infill_before_walls
|
|
||||||
min_infill_area
|
|
||||||
skin_preshrink
|
|
||||||
expand_skins_expand_distance
|
|
||||||
max_skin_angle_for_expansion
|
|
||||||
|
|
||||||
[material]
|
[material]
|
||||||
default_material_print_temperature
|
|
||||||
material_print_temperature
|
material_print_temperature
|
||||||
material_print_temperature_layer_0
|
material_print_temperature_layer_0
|
||||||
material_initial_print_temperature
|
material_initial_print_temperature
|
||||||
material_final_print_temperature
|
material_final_print_temperature
|
||||||
material_extrusion_cool_down_speed
|
|
||||||
default_material_bed_temperature
|
|
||||||
material_bed_temperature
|
material_bed_temperature
|
||||||
material_bed_temperature_layer_0
|
material_bed_temperature_layer_0
|
||||||
material_diameter
|
|
||||||
material_adhesion_tendency
|
|
||||||
material_surface_energy
|
|
||||||
material_flow
|
|
||||||
retraction_enable
|
retraction_enable
|
||||||
retract_at_layer_change
|
retract_at_layer_change
|
||||||
retraction_amount
|
retraction_amount
|
||||||
retraction_speed
|
retraction_speed
|
||||||
retraction_extra_prime_amount
|
|
||||||
retraction_min_travel
|
|
||||||
retraction_count_max
|
|
||||||
retraction_extrusion_window
|
|
||||||
material_standby_temperature
|
material_standby_temperature
|
||||||
switch_extruder_retraction_amount
|
|
||||||
switch_extruder_retraction_speeds
|
|
||||||
|
|
||||||
[speed]
|
[speed]
|
||||||
speed_print
|
speed_print
|
||||||
|
speed_infill
|
||||||
|
speed_wall
|
||||||
|
speed_wall_0
|
||||||
|
speed_wall_x
|
||||||
|
speed_topbottom
|
||||||
|
speed_support
|
||||||
|
speed_prime_tower
|
||||||
speed_travel
|
speed_travel
|
||||||
speed_layer_0
|
speed_layer_0
|
||||||
skirt_brim_speed
|
skirt_brim_speed
|
||||||
max_feedrate_z_override
|
|
||||||
speed_slowdown_layers
|
|
||||||
speed_equalize_flow_enabled
|
|
||||||
speed_equalize_flow_max
|
|
||||||
acceleration_enabled
|
acceleration_enabled
|
||||||
acceleration_print
|
|
||||||
acceleration_travel
|
|
||||||
acceleration_layer_0
|
|
||||||
acceleration_skirt_brim
|
|
||||||
jerk_enabled
|
jerk_enabled
|
||||||
jerk_print
|
|
||||||
jerk_travel
|
|
||||||
jerk_layer_0
|
|
||||||
jerk_skirt_brim
|
|
||||||
|
|
||||||
[travel]
|
[travel]
|
||||||
retraction_combing
|
retraction_combing
|
||||||
travel_retract_before_outer_wall
|
|
||||||
travel_avoid_other_parts
|
travel_avoid_other_parts
|
||||||
travel_avoid_distance
|
travel_avoid_distance
|
||||||
start_layers_at_same_position
|
|
||||||
layer_start_x
|
|
||||||
layer_start_y
|
|
||||||
retraction_hop_enabled
|
retraction_hop_enabled
|
||||||
retraction_hop_only_when_collides
|
retraction_hop_only_when_collides
|
||||||
retraction_hop
|
retraction_hop
|
||||||
|
@ -130,9 +81,12 @@ retraction_hop_after_extruder_switch
|
||||||
[cooling]
|
[cooling]
|
||||||
cool_fan_enabled
|
cool_fan_enabled
|
||||||
cool_fan_speed
|
cool_fan_speed
|
||||||
|
cool_fan_speed_min
|
||||||
|
cool_fan_speed_max
|
||||||
cool_min_layer_time_fan_speed_max
|
cool_min_layer_time_fan_speed_max
|
||||||
cool_fan_speed_0
|
cool_fan_speed_0
|
||||||
cool_fan_full_at_height
|
cool_fan_full_at_height
|
||||||
|
cool_fan_full_layer
|
||||||
cool_min_layer_time
|
cool_min_layer_time
|
||||||
cool_min_speed
|
cool_min_speed
|
||||||
cool_lift_head
|
cool_lift_head
|
||||||
|
@ -140,115 +94,45 @@ cool_lift_head
|
||||||
[support]
|
[support]
|
||||||
support_enable
|
support_enable
|
||||||
support_extruder_nr
|
support_extruder_nr
|
||||||
|
support_infill_extruder_nr
|
||||||
|
support_extruder_nr_layer_0
|
||||||
|
support_interface_extruder_nr
|
||||||
support_type
|
support_type
|
||||||
support_angle
|
support_angle
|
||||||
support_pattern
|
support_pattern
|
||||||
support_connect_zigzags
|
|
||||||
support_infill_rate
|
support_infill_rate
|
||||||
support_z_distance
|
|
||||||
support_xy_distance
|
|
||||||
support_xy_overrides_z
|
|
||||||
support_xy_distance_overhang
|
|
||||||
support_bottom_stair_step_height
|
|
||||||
support_bottom_stair_step_width
|
|
||||||
support_join_distance
|
|
||||||
support_offset
|
support_offset
|
||||||
support_infill_sparse_thickness
|
support_infill_sparse_thickness
|
||||||
gradual_support_infill_steps
|
gradual_support_infill_steps
|
||||||
gradual_support_infill_step_height
|
gradual_support_infill_step_height
|
||||||
support_interface_enable
|
support_interface_enable
|
||||||
support_interface_height
|
support_roof_enable
|
||||||
support_interface_skip_height
|
support_bottom_enable
|
||||||
support_interface_density
|
|
||||||
support_interface_pattern
|
|
||||||
support_use_towers
|
|
||||||
support_tower_diameter
|
|
||||||
support_minimal_diameter
|
|
||||||
support_tower_roof_angle
|
|
||||||
support_mesh_drop_down
|
|
||||||
|
|
||||||
[platform_adhesion]
|
[platform_adhesion]
|
||||||
prime_blob_enable
|
prime_blob_enable
|
||||||
extruder_prime_pos_x
|
|
||||||
extruder_prime_pos_y
|
|
||||||
adhesion_type
|
adhesion_type
|
||||||
adhesion_extruder_nr
|
adhesion_extruder_nr
|
||||||
skirt_line_count
|
skirt_line_count
|
||||||
skirt_gap
|
|
||||||
skirt_brim_minimal_length
|
|
||||||
brim_width
|
brim_width
|
||||||
|
brim_line_count
|
||||||
brim_outside_only
|
brim_outside_only
|
||||||
raft_margin
|
|
||||||
raft_smoothing
|
|
||||||
raft_airgap
|
|
||||||
layer_0_z_overlap
|
|
||||||
raft_surface_layers
|
|
||||||
raft_surface_thickness
|
|
||||||
raft_surface_line_width
|
|
||||||
raft_surface_line_spacing
|
|
||||||
raft_interface_thickness
|
|
||||||
raft_interface_line_width
|
|
||||||
raft_interface_line_spacing
|
|
||||||
raft_base_thickness
|
|
||||||
raft_base_line_width
|
|
||||||
raft_base_line_spacing
|
|
||||||
raft_speed
|
|
||||||
raft_acceleration
|
|
||||||
raft_jerk
|
|
||||||
raft_fan_speed
|
|
||||||
|
|
||||||
[dual]
|
[dual]
|
||||||
prime_tower_enable
|
prime_tower_enable
|
||||||
prime_tower_size
|
|
||||||
prime_tower_min_volume
|
|
||||||
prime_tower_position_x
|
prime_tower_position_x
|
||||||
prime_tower_position_y
|
prime_tower_position_y
|
||||||
prime_tower_flow
|
|
||||||
prime_tower_wipe_enabled
|
|
||||||
dual_pre_wipe
|
|
||||||
prime_tower_purge_volume
|
prime_tower_purge_volume
|
||||||
ooze_shield_enabled
|
|
||||||
ooze_shield_angle
|
|
||||||
ooze_shield_dist
|
|
||||||
|
|
||||||
[meshfix]
|
[meshfix]
|
||||||
meshfix_union_all
|
|
||||||
meshfix_union_all_remove_holes
|
|
||||||
meshfix_extensive_stitching
|
|
||||||
meshfix_keep_open_polygons
|
|
||||||
multiple_mesh_overlap
|
|
||||||
carve_multiple_volumes
|
|
||||||
alternate_carve_order
|
|
||||||
remove_empty_first_layers
|
|
||||||
|
|
||||||
[blackmagic]
|
[blackmagic]
|
||||||
print_sequence
|
print_sequence
|
||||||
infill_mesh
|
|
||||||
infill_mesh_order
|
|
||||||
cutting_mesh
|
|
||||||
mold_enabled
|
|
||||||
mold_width
|
|
||||||
mold_roof_height
|
|
||||||
mold_angle
|
|
||||||
support_mesh
|
|
||||||
anti_overhang_mesh
|
|
||||||
magic_mesh_surface_mode
|
magic_mesh_surface_mode
|
||||||
magic_spiralize
|
magic_spiralize
|
||||||
smooth_spiralized_contours
|
smooth_spiralized_contours
|
||||||
relative_extrusion
|
|
||||||
|
|
||||||
[experimental]
|
[experimental]
|
||||||
infill_enable_travel_optimization
|
conical_overhang_enabled
|
||||||
material_flow_dependent_temperature
|
support_conical_enabled
|
||||||
material_flow_temp_graph
|
adaptive_layer_height_enabled
|
||||||
meshfix_maximum_resolution
|
|
||||||
roofing_angles
|
|
||||||
roofing_pattern
|
|
||||||
slicing_tolerance
|
|
||||||
support_tree_angle
|
|
||||||
support_tree_branch_diameter
|
|
||||||
support_tree_branch_diameter_angle
|
|
||||||
support_tree_branch_distance
|
|
||||||
support_tree_collision_resolution
|
|
||||||
support_tree_enable
|
|
||||||
support_tree_wall_thickness
|
|
||||||
|
|
|
@ -9,30 +9,28 @@ layer_height
|
||||||
|
|
||||||
[shell]
|
[shell]
|
||||||
wall_thickness
|
wall_thickness
|
||||||
|
wall_line_count
|
||||||
top_bottom_thickness
|
top_bottom_thickness
|
||||||
z_seam_x
|
top_thickness
|
||||||
z_seam_y
|
top_layers
|
||||||
|
bottom_thickness
|
||||||
|
bottom_layers
|
||||||
|
xy_offset
|
||||||
|
|
||||||
[infill]
|
[infill]
|
||||||
infill_sparse_density
|
infill_sparse_density
|
||||||
gradual_infill_steps
|
infill_pattern
|
||||||
|
|
||||||
[material]
|
[material]
|
||||||
material_print_temperature
|
material_print_temperature
|
||||||
material_bed_temperature
|
material_bed_temperature
|
||||||
material_diameter
|
|
||||||
material_flow
|
|
||||||
retraction_enable
|
retraction_enable
|
||||||
|
|
||||||
[speed]
|
[speed]
|
||||||
speed_print
|
speed_print
|
||||||
speed_travel
|
|
||||||
acceleration_print
|
|
||||||
acceleration_travel
|
|
||||||
jerk_print
|
|
||||||
jerk_travel
|
|
||||||
|
|
||||||
[travel]
|
[travel]
|
||||||
|
retraction_hop_enabled
|
||||||
|
|
||||||
[cooling]
|
[cooling]
|
||||||
cool_fan_enabled
|
cool_fan_enabled
|
||||||
|
@ -41,26 +39,20 @@ cool_fan_enabled
|
||||||
support_enable
|
support_enable
|
||||||
support_extruder_nr
|
support_extruder_nr
|
||||||
support_type
|
support_type
|
||||||
|
support_angle
|
||||||
|
|
||||||
[platform_adhesion]
|
[platform_adhesion]
|
||||||
|
prime_blob_enable
|
||||||
adhesion_type
|
adhesion_type
|
||||||
adhesion_extruder_nr
|
adhesion_extruder_nr
|
||||||
brim_width
|
|
||||||
raft_airgap
|
|
||||||
layer_0_z_overlap
|
|
||||||
raft_surface_layers
|
|
||||||
|
|
||||||
[dual]
|
[dual]
|
||||||
prime_tower_enable
|
prime_tower_enable
|
||||||
prime_tower_size
|
|
||||||
prime_tower_position_x
|
prime_tower_position_x
|
||||||
prime_tower_position_y
|
prime_tower_position_y
|
||||||
|
|
||||||
[meshfix]
|
[meshfix]
|
||||||
|
|
||||||
[blackmagic]
|
[blackmagic]
|
||||||
print_sequence
|
|
||||||
infill_mesh
|
|
||||||
cutting_mesh
|
|
||||||
|
|
||||||
[experimental]
|
[experimental]
|
||||||
|
|
|
@ -8,15 +8,33 @@ weight = 3
|
||||||
layer_height
|
layer_height
|
||||||
layer_height_0
|
layer_height_0
|
||||||
line_width
|
line_width
|
||||||
|
wall_line_width
|
||||||
|
wall_line_width_0
|
||||||
|
wall_line_width_x
|
||||||
|
skin_line_width
|
||||||
|
infill_line_width
|
||||||
|
skirt_brim_line_width
|
||||||
|
support_line_width
|
||||||
|
support_interface_line_width
|
||||||
|
support_roof_line_width
|
||||||
|
support_bottom_line_width
|
||||||
|
prime_tower_line_width
|
||||||
|
initial_layer_line_width_factor
|
||||||
|
|
||||||
[shell]
|
[shell]
|
||||||
wall_extruder_nr
|
wall_extruder_nr
|
||||||
|
wall_0_extruder_nr
|
||||||
|
wall_x_extruder_nr
|
||||||
wall_thickness
|
wall_thickness
|
||||||
|
wall_line_count
|
||||||
wall_0_wipe_dist
|
wall_0_wipe_dist
|
||||||
roofing_extruder_nr
|
|
||||||
roofing_layer_count
|
roofing_layer_count
|
||||||
top_bottom_extruder_nr
|
top_bottom_extruder_nr
|
||||||
top_bottom_thickness
|
top_bottom_thickness
|
||||||
|
top_thickness
|
||||||
|
top_layers
|
||||||
|
bottom_thickness
|
||||||
|
bottom_layers
|
||||||
top_bottom_pattern
|
top_bottom_pattern
|
||||||
top_bottom_pattern_0
|
top_bottom_pattern_0
|
||||||
skin_angles
|
skin_angles
|
||||||
|
@ -25,6 +43,8 @@ optimize_wall_printing_order
|
||||||
outer_inset_first
|
outer_inset_first
|
||||||
alternate_extra_perimeter
|
alternate_extra_perimeter
|
||||||
travel_compensate_overlapping_walls_enabled
|
travel_compensate_overlapping_walls_enabled
|
||||||
|
travel_compensate_overlapping_walls_0_enabled
|
||||||
|
travel_compensate_overlapping_walls_x_enabled
|
||||||
fill_perimeter_gaps
|
fill_perimeter_gaps
|
||||||
filter_out_tiny_gaps
|
filter_out_tiny_gaps
|
||||||
fill_outline_gaps
|
fill_outline_gaps
|
||||||
|
@ -50,6 +70,7 @@ jerk_ironing
|
||||||
[infill]
|
[infill]
|
||||||
infill_extruder_nr
|
infill_extruder_nr
|
||||||
infill_sparse_density
|
infill_sparse_density
|
||||||
|
infill_line_distance
|
||||||
infill_pattern
|
infill_pattern
|
||||||
zig_zaggify_infill
|
zig_zaggify_infill
|
||||||
infill_angles
|
infill_angles
|
||||||
|
@ -57,7 +78,9 @@ infill_offset_x
|
||||||
infill_offset_y
|
infill_offset_y
|
||||||
sub_div_rad_add
|
sub_div_rad_add
|
||||||
infill_overlap
|
infill_overlap
|
||||||
|
infill_overlap_mm
|
||||||
skin_overlap
|
skin_overlap
|
||||||
|
skin_overlap_mm
|
||||||
infill_wipe_dist
|
infill_wipe_dist
|
||||||
infill_sparse_thickness
|
infill_sparse_thickness
|
||||||
gradual_infill_steps
|
gradual_infill_steps
|
||||||
|
@ -65,8 +88,13 @@ gradual_infill_step_height
|
||||||
infill_before_walls
|
infill_before_walls
|
||||||
min_infill_area
|
min_infill_area
|
||||||
skin_preshrink
|
skin_preshrink
|
||||||
|
top_skin_preshrink
|
||||||
|
bottom_skin_preshrink
|
||||||
expand_skins_expand_distance
|
expand_skins_expand_distance
|
||||||
|
top_skin_expand_distance
|
||||||
|
bottom_skin_expand_distance
|
||||||
max_skin_angle_for_expansion
|
max_skin_angle_for_expansion
|
||||||
|
min_skin_width_for_expansion
|
||||||
|
|
||||||
[material]
|
[material]
|
||||||
default_material_print_temperature
|
default_material_print_temperature
|
||||||
|
@ -75,17 +103,19 @@ material_print_temperature_layer_0
|
||||||
material_initial_print_temperature
|
material_initial_print_temperature
|
||||||
material_final_print_temperature
|
material_final_print_temperature
|
||||||
material_extrusion_cool_down_speed
|
material_extrusion_cool_down_speed
|
||||||
default_material_bed_temperature
|
|
||||||
material_bed_temperature
|
material_bed_temperature
|
||||||
material_bed_temperature_layer_0
|
material_bed_temperature_layer_0
|
||||||
material_diameter
|
material_diameter
|
||||||
material_adhesion_tendency
|
material_adhesion_tendency
|
||||||
material_surface_energy
|
material_surface_energy
|
||||||
material_flow
|
material_flow
|
||||||
|
material_flow_layer_0
|
||||||
retraction_enable
|
retraction_enable
|
||||||
retract_at_layer_change
|
retract_at_layer_change
|
||||||
retraction_amount
|
retraction_amount
|
||||||
retraction_speed
|
retraction_speed
|
||||||
|
retraction_retract_speed
|
||||||
|
retraction_prime_speed
|
||||||
retraction_extra_prime_amount
|
retraction_extra_prime_amount
|
||||||
retraction_min_travel
|
retraction_min_travel
|
||||||
retraction_count_max
|
retraction_count_max
|
||||||
|
@ -93,11 +123,25 @@ retraction_extrusion_window
|
||||||
material_standby_temperature
|
material_standby_temperature
|
||||||
switch_extruder_retraction_amount
|
switch_extruder_retraction_amount
|
||||||
switch_extruder_retraction_speeds
|
switch_extruder_retraction_speeds
|
||||||
|
switch_extruder_retraction_speed
|
||||||
|
switch_extruder_prime_speed
|
||||||
|
|
||||||
[speed]
|
[speed]
|
||||||
speed_print
|
speed_print
|
||||||
|
speed_infill
|
||||||
|
speed_wall
|
||||||
|
speed_wall_0
|
||||||
|
speed_wall_x
|
||||||
|
speed_roofing
|
||||||
|
speed_topbottom
|
||||||
|
speed_support
|
||||||
|
speed_support_infill
|
||||||
|
speed_support_interface
|
||||||
|
speed_prime_tower
|
||||||
speed_travel
|
speed_travel
|
||||||
speed_layer_0
|
speed_layer_0
|
||||||
|
speed_print_layer_0
|
||||||
|
speed_travel_layer_0
|
||||||
skirt_brim_speed
|
skirt_brim_speed
|
||||||
max_feedrate_z_override
|
max_feedrate_z_override
|
||||||
speed_slowdown_layers
|
speed_slowdown_layers
|
||||||
|
@ -105,13 +149,37 @@ speed_equalize_flow_enabled
|
||||||
speed_equalize_flow_max
|
speed_equalize_flow_max
|
||||||
acceleration_enabled
|
acceleration_enabled
|
||||||
acceleration_print
|
acceleration_print
|
||||||
|
acceleration_infill
|
||||||
|
acceleration_wall
|
||||||
|
acceleration_wall_0
|
||||||
|
acceleration_wall_x
|
||||||
|
acceleration_roofing
|
||||||
|
acceleration_topbottom
|
||||||
|
acceleration_support
|
||||||
|
acceleration_support_infill
|
||||||
|
acceleration_support_interface
|
||||||
|
acceleration_prime_tower
|
||||||
acceleration_travel
|
acceleration_travel
|
||||||
acceleration_layer_0
|
acceleration_layer_0
|
||||||
|
acceleration_print_layer_0
|
||||||
|
acceleration_travel_layer_0
|
||||||
acceleration_skirt_brim
|
acceleration_skirt_brim
|
||||||
jerk_enabled
|
jerk_enabled
|
||||||
jerk_print
|
jerk_print
|
||||||
|
jerk_infill
|
||||||
|
jerk_wall
|
||||||
|
jerk_wall_0
|
||||||
|
jerk_wall_x
|
||||||
|
jerk_roofing
|
||||||
|
jerk_topbottom
|
||||||
|
jerk_support
|
||||||
|
jerk_support_infill
|
||||||
|
jerk_support_interface
|
||||||
|
jerk_prime_tower
|
||||||
jerk_travel
|
jerk_travel
|
||||||
jerk_layer_0
|
jerk_layer_0
|
||||||
|
jerk_print_layer_0
|
||||||
|
jerk_travel_layer_0
|
||||||
jerk_skirt_brim
|
jerk_skirt_brim
|
||||||
|
|
||||||
[travel]
|
[travel]
|
||||||
|
@ -130,9 +198,12 @@ retraction_hop_after_extruder_switch
|
||||||
[cooling]
|
[cooling]
|
||||||
cool_fan_enabled
|
cool_fan_enabled
|
||||||
cool_fan_speed
|
cool_fan_speed
|
||||||
|
cool_fan_speed_min
|
||||||
|
cool_fan_speed_max
|
||||||
cool_min_layer_time_fan_speed_max
|
cool_min_layer_time_fan_speed_max
|
||||||
cool_fan_speed_0
|
cool_fan_speed_0
|
||||||
cool_fan_full_at_height
|
cool_fan_full_at_height
|
||||||
|
cool_fan_full_layer
|
||||||
cool_min_layer_time
|
cool_min_layer_time
|
||||||
cool_min_speed
|
cool_min_speed
|
||||||
cool_lift_head
|
cool_lift_head
|
||||||
|
@ -140,12 +211,21 @@ cool_lift_head
|
||||||
[support]
|
[support]
|
||||||
support_enable
|
support_enable
|
||||||
support_extruder_nr
|
support_extruder_nr
|
||||||
|
support_infill_extruder_nr
|
||||||
|
support_extruder_nr_layer_0
|
||||||
|
support_interface_extruder_nr
|
||||||
|
support_roof_extruder_nr
|
||||||
|
support_bottom_extruder_nr
|
||||||
support_type
|
support_type
|
||||||
support_angle
|
support_angle
|
||||||
support_pattern
|
support_pattern
|
||||||
|
zig_zaggify_support
|
||||||
support_connect_zigzags
|
support_connect_zigzags
|
||||||
support_infill_rate
|
support_infill_rate
|
||||||
|
support_line_distance
|
||||||
support_z_distance
|
support_z_distance
|
||||||
|
support_top_distance
|
||||||
|
support_bottom_distance
|
||||||
support_xy_distance
|
support_xy_distance
|
||||||
support_xy_overrides_z
|
support_xy_overrides_z
|
||||||
support_xy_distance_overhang
|
support_xy_distance_overhang
|
||||||
|
@ -157,9 +237,15 @@ support_infill_sparse_thickness
|
||||||
gradual_support_infill_steps
|
gradual_support_infill_steps
|
||||||
gradual_support_infill_step_height
|
gradual_support_infill_step_height
|
||||||
support_interface_enable
|
support_interface_enable
|
||||||
|
support_roof_enable
|
||||||
|
support_bottom_enable
|
||||||
support_interface_height
|
support_interface_height
|
||||||
|
support_roof_height
|
||||||
|
support_bottom_height
|
||||||
support_interface_skip_height
|
support_interface_skip_height
|
||||||
support_interface_density
|
support_interface_density
|
||||||
|
support_roof_density
|
||||||
|
support_bottom_density
|
||||||
support_interface_pattern
|
support_interface_pattern
|
||||||
support_use_towers
|
support_use_towers
|
||||||
support_tower_diameter
|
support_tower_diameter
|
||||||
|
@ -169,19 +255,17 @@ support_mesh_drop_down
|
||||||
|
|
||||||
[platform_adhesion]
|
[platform_adhesion]
|
||||||
prime_blob_enable
|
prime_blob_enable
|
||||||
extruder_prime_pos_x
|
|
||||||
extruder_prime_pos_y
|
|
||||||
adhesion_type
|
adhesion_type
|
||||||
adhesion_extruder_nr
|
adhesion_extruder_nr
|
||||||
skirt_line_count
|
skirt_line_count
|
||||||
skirt_gap
|
skirt_gap
|
||||||
skirt_brim_minimal_length
|
skirt_brim_minimal_length
|
||||||
brim_width
|
brim_width
|
||||||
|
brim_line_count
|
||||||
brim_outside_only
|
brim_outside_only
|
||||||
raft_margin
|
raft_margin
|
||||||
raft_smoothing
|
raft_smoothing
|
||||||
raft_airgap
|
raft_airgap
|
||||||
layer_0_z_overlap
|
|
||||||
raft_surface_layers
|
raft_surface_layers
|
||||||
raft_surface_thickness
|
raft_surface_thickness
|
||||||
raft_surface_line_width
|
raft_surface_line_width
|
||||||
|
@ -199,8 +283,10 @@ raft_fan_speed
|
||||||
|
|
||||||
[dual]
|
[dual]
|
||||||
prime_tower_enable
|
prime_tower_enable
|
||||||
|
prime_tower_circular
|
||||||
prime_tower_size
|
prime_tower_size
|
||||||
prime_tower_min_volume
|
prime_tower_min_volume
|
||||||
|
prime_tower_wall_thickness
|
||||||
prime_tower_position_x
|
prime_tower_position_x
|
||||||
prime_tower_position_y
|
prime_tower_position_y
|
||||||
prime_tower_flow
|
prime_tower_flow
|
||||||
|
@ -238,8 +324,25 @@ smooth_spiralized_contours
|
||||||
relative_extrusion
|
relative_extrusion
|
||||||
|
|
||||||
[experimental]
|
[experimental]
|
||||||
|
support_tree_enable
|
||||||
|
support_tree_angle
|
||||||
|
support_tree_branch_distance
|
||||||
|
support_tree_branch_diameter
|
||||||
|
support_tree_branch_diameter_angle
|
||||||
|
support_tree_collision_resolution
|
||||||
|
support_tree_wall_thickness
|
||||||
|
support_tree_wall_count
|
||||||
|
slicing_tolerance
|
||||||
|
roofing_line_width
|
||||||
|
roofing_pattern
|
||||||
|
roofing_angles
|
||||||
|
infill_enable_travel_optimization
|
||||||
|
material_flow_dependent_temperature
|
||||||
|
material_flow_temp_graph
|
||||||
|
meshfix_maximum_resolution
|
||||||
support_skip_some_zags
|
support_skip_some_zags
|
||||||
support_skip_zag_per_mm
|
support_skip_zag_per_mm
|
||||||
|
support_zag_skip_count
|
||||||
draft_shield_enabled
|
draft_shield_enabled
|
||||||
draft_shield_dist
|
draft_shield_dist
|
||||||
draft_shield_height_limitation
|
draft_shield_height_limitation
|
||||||
|
@ -267,19 +370,34 @@ infill_hollow
|
||||||
magic_fuzzy_skin_enabled
|
magic_fuzzy_skin_enabled
|
||||||
magic_fuzzy_skin_thickness
|
magic_fuzzy_skin_thickness
|
||||||
magic_fuzzy_skin_point_density
|
magic_fuzzy_skin_point_density
|
||||||
|
magic_fuzzy_skin_point_dist
|
||||||
flow_rate_max_extrusion_offset
|
flow_rate_max_extrusion_offset
|
||||||
flow_rate_extrusion_offset_factor
|
flow_rate_extrusion_offset_factor
|
||||||
infill_enable_travel_optimization
|
wireframe_enabled
|
||||||
material_flow_dependent_temperature
|
wireframe_height
|
||||||
material_flow_temp_graph
|
wireframe_roof_inset
|
||||||
meshfix_maximum_resolution
|
wireframe_printspeed
|
||||||
roofing_angles
|
wireframe_printspeed_bottom
|
||||||
roofing_pattern
|
wireframe_printspeed_up
|
||||||
slicing_tolerance
|
wireframe_printspeed_down
|
||||||
support_tree_angle
|
wireframe_printspeed_flat
|
||||||
support_tree_branch_diameter
|
wireframe_flow
|
||||||
support_tree_branch_diameter_angle
|
wireframe_flow_connection
|
||||||
support_tree_branch_distance
|
wireframe_flow_flat
|
||||||
support_tree_collision_resolution
|
wireframe_top_delay
|
||||||
support_tree_enable
|
wireframe_bottom_delay
|
||||||
support_tree_wall_thickness
|
wireframe_flat_delay
|
||||||
|
wireframe_up_half_speed
|
||||||
|
wireframe_top_jump
|
||||||
|
wireframe_fall_down
|
||||||
|
wireframe_drag_along
|
||||||
|
wireframe_strategy
|
||||||
|
wireframe_straight_before_down
|
||||||
|
wireframe_roof_fall_down
|
||||||
|
wireframe_roof_drag_along
|
||||||
|
wireframe_roof_outer_delay
|
||||||
|
wireframe_nozzle_clearance
|
||||||
|
adaptive_layer_height_enabled
|
||||||
|
adaptive_layer_height_variation
|
||||||
|
adaptive_layer_height_variation_step
|
||||||
|
adaptive_layer_height_threshold
|
||||||
|
|
|
@ -236,6 +236,16 @@ Item
|
||||||
onTriggered: CuraActions.deleteSelection();
|
onTriggered: CuraActions.deleteSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Action //Also add backspace as the same function as delete because on Macintosh keyboards the button called "delete" is actually a backspace, and the user expects it to function as a delete.
|
||||||
|
{
|
||||||
|
id: backspaceSelectionAction
|
||||||
|
text: catalog.i18ncp("@action:inmenu menubar:edit", "Delete &Selected Model", "Delete &Selected Models", UM.Selection.selectionCount)
|
||||||
|
enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection
|
||||||
|
iconName: "edit-delete"
|
||||||
|
shortcut: StandardKey.Backspace
|
||||||
|
onTriggered: CuraActions.deleteSelection()
|
||||||
|
}
|
||||||
|
|
||||||
Action
|
Action
|
||||||
{
|
{
|
||||||
id: centerSelectionAction;
|
id: centerSelectionAction;
|
||||||
|
|
|
@ -490,6 +490,14 @@ UM.MainWindow
|
||||||
collapseSidebarAnimation.start();
|
collapseSidebarAnimation.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea
|
||||||
|
{
|
||||||
|
visible: UM.Controller.activeStage.sidebarComponent != ""
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.AllButtons
|
||||||
|
onWheel: wheel.accepted = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UM.MessageStack
|
UM.MessageStack
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.2 as UM
|
||||||
|
@ -12,7 +12,7 @@ Menu
|
||||||
id: menu
|
id: menu
|
||||||
title: "Build plate"
|
title: "Build plate"
|
||||||
|
|
||||||
property Cura.BuildPlateModel buildPlateModel: CuraApplication.getBuildPlateModel()
|
property var buildPlateModel: CuraApplication.getBuildPlateModel()
|
||||||
|
|
||||||
Instantiator
|
Instantiator
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@ Menu
|
||||||
|
|
||||||
property bool shouldShowExtruders: machineExtruderCount.properties.value > 1;
|
property bool shouldShowExtruders: machineExtruderCount.properties.value > 1;
|
||||||
|
|
||||||
property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
|
property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
|
||||||
|
|
||||||
// Selection-related actions.
|
// Selection-related actions.
|
||||||
MenuItem { action: Cura.Actions.centerSelection; }
|
MenuItem { action: Cura.Actions.centerSelection; }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.2 as UM
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2017 Ultimaker B.V.
|
// Copyright (c) 2017 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.2 as UM
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.2 as UM
|
||||||
|
@ -13,11 +13,11 @@ Menu
|
||||||
|
|
||||||
Instantiator
|
Instantiator
|
||||||
{
|
{
|
||||||
model: Cura.QualityProfilesModel
|
model: Cura.QualityProfilesDropDownMenuModel
|
||||||
|
|
||||||
MenuItem
|
MenuItem
|
||||||
{
|
{
|
||||||
text: (model.layer_height != "") ? model.name + " - " + model.layer_height : model.name
|
text: (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name
|
checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name
|
||||||
exclusiveGroup: group
|
exclusiveGroup: group
|
||||||
|
@ -34,18 +34,18 @@ Menu
|
||||||
MenuSeparator
|
MenuSeparator
|
||||||
{
|
{
|
||||||
id: customSeparator
|
id: customSeparator
|
||||||
visible: Cura.CustomQualityProfilesModel.rowCount > 0
|
visible: Cura.CustomQualityProfilesDropDownMenuModel.rowCount > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Instantiator
|
Instantiator
|
||||||
{
|
{
|
||||||
id: customProfileInstantiator
|
id: customProfileInstantiator
|
||||||
model: Cura.CustomQualityProfilesModel
|
model: Cura.CustomQualityProfilesDropDownMenuModel
|
||||||
|
|
||||||
Connections
|
Connections
|
||||||
{
|
{
|
||||||
target: Cura.CustomQualityProfilesModel
|
target: Cura.CustomQualityProfilesDropDownMenuModel
|
||||||
onModelReset: customSeparator.visible = Cura.CustomQualityProfilesModel.rowCount() > 0
|
onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.rowCount() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuItem
|
MenuItem
|
||||||
|
|
|
@ -13,7 +13,7 @@ Menu
|
||||||
id: base
|
id: base
|
||||||
enabled: !PrintInformation.preSliced
|
enabled: !PrintInformation.preSliced
|
||||||
|
|
||||||
property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
|
property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
|
||||||
|
|
||||||
// main views
|
// main views
|
||||||
Instantiator
|
Instantiator
|
||||||
|
|
|
@ -31,9 +31,9 @@ Rectangle
|
||||||
border.width: UM.Theme.getSize("default_lining").width
|
border.width: UM.Theme.getSize("default_lining").width
|
||||||
border.color: UM.Theme.getColor("lining")
|
border.color: UM.Theme.getColor("lining")
|
||||||
|
|
||||||
property bool collapsed: true;
|
property bool collapsed: true
|
||||||
|
|
||||||
property Cura.MultiBuildPlateModel multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
|
property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
|
||||||
|
|
||||||
SystemPalette { id: palette }
|
SystemPalette { id: palette }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2016 Ultimaker B.V.
|
// Copyright (c) 2016 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Window 2.1
|
import QtQuick.Window 2.1
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2017 Ultimaker B.V.
|
// Copyright (c) 2017 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ TabView
|
||||||
{
|
{
|
||||||
id: base
|
id: base
|
||||||
|
|
||||||
|
property QtObject materialManager: CuraApplication.getMaterialManager()
|
||||||
|
|
||||||
property QtObject properties
|
property QtObject properties
|
||||||
property var currentMaterialNode: null
|
property var currentMaterialNode: null
|
||||||
|
|
||||||
|
@ -214,7 +216,8 @@ TabView
|
||||||
confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
|
confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
|
||||||
|
|
||||||
confirmDiameterChangeDialog.open()
|
confirmDiameterChangeDialog.open()
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value);
|
Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value);
|
||||||
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString());
|
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString());
|
||||||
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
|
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
|
||||||
|
@ -396,13 +399,15 @@ TabView
|
||||||
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
|
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
UM.ContainerPropertyProvider {
|
UM.ContainerPropertyProvider
|
||||||
|
{
|
||||||
id: materialPropertyProvider
|
id: materialPropertyProvider
|
||||||
containerId: base.containerId
|
containerId: base.containerId
|
||||||
watchedProperties: [ "value" ]
|
watchedProperties: [ "value" ]
|
||||||
key: model.key
|
key: model.key
|
||||||
}
|
}
|
||||||
UM.ContainerPropertyProvider {
|
UM.ContainerPropertyProvider
|
||||||
|
{
|
||||||
id: machinePropertyProvider
|
id: machinePropertyProvider
|
||||||
containerId: Cura.MachineManager.activeDefinitionId
|
containerId: Cura.MachineManager.activeDefinitionId
|
||||||
watchedProperties: [ "value" ]
|
watchedProperties: [ "value" ]
|
||||||
|
@ -497,7 +502,7 @@ TabView
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the values
|
// update the values
|
||||||
Cura.ContainerManager.setMaterialName(base.currentMaterialNode, new_name)
|
base.materialManager.setMaterialName(base.currentMaterialNode, new_name)
|
||||||
materialProperties.name = new_name
|
materialProperties.name = new_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Uranium is released under the terms of the LGPLv3 or higher.
|
// Uranium is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
|
@ -13,6 +13,8 @@ import Cura 1.0 as Cura
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
id: base
|
id: base
|
||||||
|
|
||||||
|
property QtObject materialManager: CuraApplication.getMaterialManager()
|
||||||
property var resetEnabled: false // Keep PreferencesDialog happy
|
property var resetEnabled: false // Keep PreferencesDialog happy
|
||||||
|
|
||||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||||
|
@ -37,12 +39,14 @@ Item
|
||||||
|
|
||||||
property var hasCurrentItem: materialListView.currentItem != null
|
property var hasCurrentItem: materialListView.currentItem != null
|
||||||
|
|
||||||
property var currentItem: { // is soon to be overwritten
|
property var currentItem:
|
||||||
|
{ // is soon to be overwritten
|
||||||
var current_index = materialListView.currentIndex;
|
var current_index = materialListView.currentIndex;
|
||||||
return materialsModel.getItem(current_index);
|
return materialsModel.getItem(current_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
property var isCurrentItemActivated: {
|
property var isCurrentItemActivated:
|
||||||
|
{
|
||||||
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
||||||
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
|
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
|
||||||
return base.currentItem.root_material_id == root_material_id;
|
return base.currentItem.root_material_id == root_material_id;
|
||||||
|
@ -51,7 +55,8 @@ Item
|
||||||
Row // Button Row
|
Row // Button Row
|
||||||
{
|
{
|
||||||
id: buttonRow
|
id: buttonRow
|
||||||
anchors {
|
anchors
|
||||||
|
{
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
top: titleLabel.bottom
|
top: titleLabel.bottom
|
||||||
|
@ -59,11 +64,13 @@ Item
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
|
||||||
// Activate button
|
// Activate button
|
||||||
Button {
|
Button
|
||||||
|
{
|
||||||
text: catalog.i18nc("@action:button", "Activate")
|
text: catalog.i18nc("@action:button", "Activate")
|
||||||
iconName: "list-activate"
|
iconName: "list-activate"
|
||||||
enabled: !isCurrentItemActivated
|
enabled: !isCurrentItemActivated
|
||||||
onClicked: {
|
onClicked:
|
||||||
|
{
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
||||||
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
||||||
|
@ -72,44 +79,52 @@ Item
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create button
|
// Create button
|
||||||
Button {
|
Button
|
||||||
|
{
|
||||||
text: catalog.i18nc("@action:button", "Create")
|
text: catalog.i18nc("@action:button", "Create")
|
||||||
iconName: "list-add"
|
iconName: "list-add"
|
||||||
onClicked: {
|
onClicked:
|
||||||
|
{
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
base.newRootMaterialIdToSwitchTo = Cura.ContainerManager.createMaterial();
|
base.newRootMaterialIdToSwitchTo = base.materialManager.createMaterial();
|
||||||
base.toActivateNewMaterial = true;
|
base.toActivateNewMaterial = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duplicate button
|
// Duplicate button
|
||||||
Button {
|
Button
|
||||||
|
{
|
||||||
text: catalog.i18nc("@action:button", "Duplicate");
|
text: catalog.i18nc("@action:button", "Duplicate");
|
||||||
iconName: "list-add"
|
iconName: "list-add"
|
||||||
enabled: base.hasCurrentItem
|
enabled: base.hasCurrentItem
|
||||||
onClicked: {
|
onClicked:
|
||||||
|
{
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
base.newRootMaterialIdToSwitchTo = Cura.ContainerManager.duplicateMaterial(base.currentItem.container_node);
|
base.newRootMaterialIdToSwitchTo = base.materialManager.duplicateMaterial(base.currentItem.container_node);
|
||||||
base.toActivateNewMaterial = true;
|
base.toActivateNewMaterial = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove button
|
// Remove button
|
||||||
Button {
|
Button
|
||||||
|
{
|
||||||
text: catalog.i18nc("@action:button", "Remove")
|
text: catalog.i18nc("@action:button", "Remove")
|
||||||
iconName: "list-remove"
|
iconName: "list-remove"
|
||||||
enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated
|
enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated
|
||||||
onClicked: {
|
onClicked:
|
||||||
|
{
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
confirmRemoveMaterialDialog.open();
|
confirmRemoveMaterialDialog.open();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import button
|
// Import button
|
||||||
Button {
|
Button
|
||||||
|
{
|
||||||
text: catalog.i18nc("@action:button", "Import")
|
text: catalog.i18nc("@action:button", "Import")
|
||||||
iconName: "document-import"
|
iconName: "document-import"
|
||||||
onClicked: {
|
onClicked:
|
||||||
|
{
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
importMaterialDialog.open();
|
importMaterialDialog.open();
|
||||||
}
|
}
|
||||||
|
@ -117,10 +132,12 @@ Item
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export button
|
// Export button
|
||||||
Button {
|
Button
|
||||||
|
{
|
||||||
text: catalog.i18nc("@action:button", "Export")
|
text: catalog.i18nc("@action:button", "Export")
|
||||||
iconName: "document-export"
|
iconName: "document-export"
|
||||||
onClicked: {
|
onClicked:
|
||||||
|
{
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
exportMaterialDialog.open();
|
exportMaterialDialog.open();
|
||||||
}
|
}
|
||||||
|
@ -181,7 +198,7 @@ Item
|
||||||
|
|
||||||
onYes:
|
onYes:
|
||||||
{
|
{
|
||||||
Cura.ContainerManager.removeMaterial(base.currentItem.container_node);
|
base.materialManager.removeMaterial(base.currentItem.container_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +298,6 @@ Item
|
||||||
}
|
}
|
||||||
visible: text != ""
|
visible: text != ""
|
||||||
text: {
|
text: {
|
||||||
// OLD STUFF
|
|
||||||
var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
|
var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
|
||||||
if (Cura.MachineManager.hasVariants)
|
if (Cura.MachineManager.hasVariants)
|
||||||
{
|
{
|
||||||
|
@ -343,10 +359,19 @@ Item
|
||||||
|
|
||||||
Row
|
Row
|
||||||
{
|
{
|
||||||
|
id: materialRow
|
||||||
spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
|
spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
property bool isItemActivated:
|
||||||
|
{
|
||||||
|
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
||||||
|
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
|
||||||
|
return model.root_material_id == root_material_id;
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
width: Math.floor(parent.height * 0.8)
|
width: Math.floor(parent.height * 0.8)
|
||||||
|
@ -360,22 +385,14 @@ Item
|
||||||
width: Math.floor((parent.width * 0.3))
|
width: Math.floor((parent.width * 0.3))
|
||||||
text: model.material
|
text: model.material
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.italic: { // TODO: make it easier
|
font.italic: materialRow.isItemActivated
|
||||||
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
|
||||||
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
|
|
||||||
return model.root_material_id == root_material_id
|
|
||||||
}
|
|
||||||
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
|
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
|
||||||
}
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
text: (model.name != model.material) ? model.name : ""
|
text: (model.name != model.material) ? model.name : ""
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
font.italic: { // TODO: make it easier
|
font.italic: materialRow.isItemActivated
|
||||||
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
|
||||||
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
|
|
||||||
return model.root_material_id == root_material_id;
|
|
||||||
}
|
|
||||||
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
|
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
import UM 1.2 as UM
|
import UM 1.2 as UM
|
||||||
|
@ -85,7 +85,7 @@ Tab
|
||||||
model: Cura.QualitySettingsModel
|
model: Cura.QualitySettingsModel
|
||||||
{
|
{
|
||||||
id: qualitySettings
|
id: qualitySettings
|
||||||
extruderPosition: base.extruderPosition
|
selectedPosition: base.extruderPosition
|
||||||
selectedQualityItem: base.qualityItem
|
selectedQualityItem: base.qualityItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Uranium is released under the terms of the LGPLv3 or higher.
|
// Uranium is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
|
@ -13,6 +13,8 @@ import Cura 1.0 as Cura
|
||||||
Item
|
Item
|
||||||
{
|
{
|
||||||
id: base
|
id: base
|
||||||
|
|
||||||
|
property QtObject qualityManager: CuraApplication.getQualityManager()
|
||||||
property var resetEnabled: false // Keep PreferencesDialog happy
|
property var resetEnabled: false // Keep PreferencesDialog happy
|
||||||
property var extrudersModel: Cura.ExtrudersModel {}
|
property var extrudersModel: Cura.ExtrudersModel {}
|
||||||
|
|
||||||
|
@ -173,7 +175,7 @@ Item
|
||||||
{
|
{
|
||||||
base.newQualityNameToSelect = newName; // We want to switch to the new profile once it's created
|
base.newQualityNameToSelect = newName; // We want to switch to the new profile once it's created
|
||||||
base.toActivateNewQuality = true;
|
base.toActivateNewQuality = true;
|
||||||
Cura.ContainerManager.createQualityChanges(newName);
|
base.qualityManager.createQualityChanges(newName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +224,7 @@ Item
|
||||||
object: "<new name>"
|
object: "<new name>"
|
||||||
onAccepted:
|
onAccepted:
|
||||||
{
|
{
|
||||||
Cura.ContainerManager.duplicateQualityChanges(newName, base.currentItem);
|
base.qualityManager.duplicateQualityChanges(newName, base.currentItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,9 +241,9 @@ Item
|
||||||
|
|
||||||
onYes:
|
onYes:
|
||||||
{
|
{
|
||||||
Cura.ContainerManager.removeQualityChangesGroup(base.currentItem.quality_changes_group);
|
base.qualityManager.removeQualityChangesGroup(base.currentItem.quality_changes_group);
|
||||||
// reset current item to the first if available
|
// reset current item to the first if available
|
||||||
qualityListView.currentIndex = -1; // TODO: Reset selection.
|
qualityListView.currentIndex = -1; // Reset selection.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +255,7 @@ Item
|
||||||
object: "<new name>"
|
object: "<new name>"
|
||||||
onAccepted:
|
onAccepted:
|
||||||
{
|
{
|
||||||
var actualNewName = Cura.ContainerManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName);
|
var actualNewName = base.qualityManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName);
|
||||||
base.newQualityNameToSelect = actualNewName; // Select the new name after the model gets updated
|
base.newQualityNameToSelect = actualNewName; // Select the new name after the model gets updated
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,7 +266,7 @@ Item
|
||||||
id: importDialog
|
id: importDialog
|
||||||
title: catalog.i18nc("@title:window", "Import Profile")
|
title: catalog.i18nc("@title:window", "Import Profile")
|
||||||
selectExisting: true
|
selectExisting: true
|
||||||
nameFilters: qualitiesModel.getFileNameFilters("profile_reader") // TODO: make this easier
|
nameFilters: qualitiesModel.getFileNameFilters("profile_reader")
|
||||||
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
||||||
onAccepted:
|
onAccepted:
|
||||||
{
|
{
|
||||||
|
@ -290,11 +292,10 @@ Item
|
||||||
id: exportDialog
|
id: exportDialog
|
||||||
title: catalog.i18nc("@title:window", "Export Profile")
|
title: catalog.i18nc("@title:window", "Export Profile")
|
||||||
selectExisting: false
|
selectExisting: false
|
||||||
nameFilters: qualitiesModel.getFileNameFilters("profile_writer") // TODO: make this easier
|
nameFilters: qualitiesModel.getFileNameFilters("profile_writer")
|
||||||
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
folder: CuraApplication.getDefaultPath("dialog_profile_path")
|
||||||
onAccepted:
|
onAccepted:
|
||||||
{
|
{
|
||||||
// TODO: make this easier
|
|
||||||
var result = Cura.ContainerManager.exportQualityChangesGroup(base.currentItem.quality_changes_group,
|
var result = Cura.ContainerManager.exportQualityChangesGroup(base.currentItem.quality_changes_group,
|
||||||
fileUrl, selectedNameFilter);
|
fileUrl, selectedNameFilter);
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ Item
|
||||||
TextField
|
TextField
|
||||||
{
|
{
|
||||||
id: filter;
|
id: filter;
|
||||||
|
height: parent.height
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: clearFilterButton.left
|
anchors.right: clearFilterButton.left
|
||||||
anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
|
anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
|
||||||
|
|
|
@ -515,15 +515,12 @@ Rectangle
|
||||||
weights = ["0"];
|
weights = ["0"];
|
||||||
costs = ["0.00"];
|
costs = ["0.00"];
|
||||||
}
|
}
|
||||||
|
var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g";
|
||||||
if(someCostsKnown)
|
if(someCostsKnown)
|
||||||
{
|
{
|
||||||
return catalog.i18nc("@label Print estimates: m for meters, g for grams, %4 is currency and %3 is print cost", "%1m / ~ %2g / ~ %4 %3").arg(lengths.join(" + "))
|
result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency");
|
||||||
.arg(weights.join(" + ")).arg(costs.join(" + ")).arg(UM.Preferences.getValue("cura/currency"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return catalog.i18nc("@label Print estimates: m for meters, g for grams", "%1m / ~ %2g").arg(lengths.join(" + ")).arg(weights.join(" + "));
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
MouseArea
|
MouseArea
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2015 Ultimaker B.V.
|
// Copyright (c) 2015 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 2.0
|
import QtQuick.Controls 2.0
|
||||||
|
|
||||||
import "Settings"
|
import "Settings"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2018 Ultimaker B.V.
|
// Copyright (c) 2018 Ultimaker B.V.
|
||||||
// Cura is released under the terms of the LGPLv3 or higher.
|
// Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.8
|
import QtQuick 2.7
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
@ -58,7 +58,7 @@ Item
|
||||||
running: false
|
running: false
|
||||||
repeat: false
|
repeat: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
var item = Cura.QualityProfilesModel.getItem(qualitySlider.value);
|
var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value);
|
||||||
Cura.MachineManager.activeQualityGroup = item.quality_group;
|
Cura.MachineManager.activeQualityGroup = item.quality_group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,8 +103,8 @@ Item
|
||||||
var availableMin = -1
|
var availableMin = -1
|
||||||
var availableMax = -1
|
var availableMax = -1
|
||||||
|
|
||||||
for (var i = 0; i < Cura.QualityProfilesModel.rowCount(); i++) {
|
for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) {
|
||||||
var qualityItem = Cura.QualityProfilesModel.getItem(i)
|
var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i)
|
||||||
|
|
||||||
// Add each quality item to the UI quality model
|
// Add each quality item to the UI quality model
|
||||||
qualityModel.append(qualityItem)
|
qualityModel.append(qualityItem)
|
||||||
|
@ -166,7 +166,7 @@ Item
|
||||||
qualityModel.existingQualityProfile = 0
|
qualityModel.existingQualityProfile = 0
|
||||||
|
|
||||||
// check, the ticks count cannot be less than zero
|
// check, the ticks count cannot be less than zero
|
||||||
qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesModel.rowCount() - 1)
|
qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,13 +192,13 @@ Item
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2)
|
anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2)
|
||||||
color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
|
color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
|
||||||
text:
|
text:
|
||||||
{
|
{
|
||||||
var result = ""
|
var result = ""
|
||||||
if(Cura.MachineManager.activeMachine != null)
|
if(Cura.MachineManager.activeMachine != null)
|
||||||
{
|
{
|
||||||
result = Cura.QualityProfilesModel.getItem(index).layer_height_without_unit
|
result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height
|
||||||
|
|
||||||
if(result == undefined)
|
if(result == undefined)
|
||||||
{
|
{
|
||||||
|
@ -263,7 +263,7 @@ Item
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: Cura.QualityProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
|
color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
|
||||||
width: 1 * screenScaleFactor
|
width: 1 * screenScaleFactor
|
||||||
height: 6 * screenScaleFactor
|
height: 6 * screenScaleFactor
|
||||||
y: 0
|
y: 0
|
||||||
|
@ -401,9 +401,9 @@ Item
|
||||||
// if the current profile is user-created, switch to a built-in quality
|
// if the current profile is user-created, switch to a built-in quality
|
||||||
if (Cura.SimpleModeSettingsManager.isProfileUserCreated)
|
if (Cura.SimpleModeSettingsManager.isProfileUserCreated)
|
||||||
{
|
{
|
||||||
if (Cura.QualityProfilesModel.rowCount() > 0)
|
if (Cura.QualityProfilesDropDownMenuModel.rowCount() > 0)
|
||||||
{
|
{
|
||||||
var item = Cura.QualityProfilesModel.getItem(0);
|
var item = Cura.QualityProfilesDropDownMenuModel.getItem(0);
|
||||||
Cura.MachineManager.activeQualityGroup = item.quality_group;
|
Cura.MachineManager.activeQualityGroup = item.quality_group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
[general]
|
|
||||||
version = 2
|
|
||||||
name = Fast
|
|
||||||
definition = abax_pri3
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
setting_version = 4
|
|
||||||
type = quality
|
|
||||||
quality_type = fast
|
|
||||||
weight = -1
|
|
||||||
global_quality = True
|
|
||||||
|
|
||||||
[values]
|
|
||||||
layer_height = 0.2
|
|
|
@ -1,14 +0,0 @@
|
||||||
[general]
|
|
||||||
version = 2
|
|
||||||
name = Extra Fine
|
|
||||||
definition = abax_pri3
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
setting_version = 4
|
|
||||||
type = quality
|
|
||||||
quality_type = high
|
|
||||||
weight = 1
|
|
||||||
global_quality = True
|
|
||||||
|
|
||||||
[values]
|
|
||||||
layer_height = 0.1
|
|
|
@ -1,14 +0,0 @@
|
||||||
[general]
|
|
||||||
version = 2
|
|
||||||
name = Fine
|
|
||||||
definition = abax_pri3
|
|
||||||
|
|
||||||
[metadata]
|
|
||||||
setting_version = 4
|
|
||||||
type = quality
|
|
||||||
quality_type = normal
|
|
||||||
weight = 0
|
|
||||||
global_quality = True
|
|
||||||
|
|
||||||
[values]
|
|
||||||
layer_height = 0.2
|
|
|
@ -1,16 +1,17 @@
|
||||||
[general]
|
[general]
|
||||||
version = 2
|
version = 2
|
||||||
name = Fast
|
name = Fine
|
||||||
definition = abax_pri3
|
definition = abax_pri3
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
type = quality
|
type = quality
|
||||||
quality_type = fast
|
quality_type = normal
|
||||||
weight = -1
|
weight = -1
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
layer_height = 0.2
|
||||||
wall_thickness = 1.05
|
wall_thickness = 1.05
|
||||||
top_bottom_thickness = 0.8
|
top_bottom_thickness = 0.8
|
||||||
infill_sparse_density = 20
|
infill_sparse_density = 20
|
||||||
|
|
|
@ -11,6 +11,7 @@ weight = 1
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
layer_height = 0.1
|
||||||
wall_thickness = 1.05
|
wall_thickness = 1.05
|
||||||
top_bottom_thickness = 0.8
|
top_bottom_thickness = 0.8
|
||||||
infill_sparse_density = 20
|
infill_sparse_density = 20
|
||||||
|
|
|
@ -11,6 +11,7 @@ weight = 0
|
||||||
material = generic_pla
|
material = generic_pla
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
layer_height = 0.2
|
||||||
wall_thickness = 1.05
|
wall_thickness = 1.05
|
||||||
top_bottom_thickness = 0.8
|
top_bottom_thickness = 0.8
|
||||||
infill_sparse_density = 20
|
infill_sparse_density = 20
|
||||||
|
|
|
@ -12,9 +12,10 @@ material = fabtotum_abs
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
adhesion_type = raft
|
adhesion_type = raft
|
||||||
|
speed_print = 80
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
layer_height_0 = 0.2
|
layer_height_0 = 0.2
|
||||||
cool_fan_enabled = True
|
cool_fan_enabled = False
|
||||||
cool_fan_full_at_height = 0.4
|
cool_fan_full_at_height = 0.4
|
||||||
cool_fan_speed = 50
|
cool_fan_speed = 50
|
||||||
cool_fan_speed_max = 50
|
cool_fan_speed_max = 50
|
||||||
|
|
|
@ -12,9 +12,10 @@ material = fabtotum_abs
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
adhesion_type = raft
|
adhesion_type = raft
|
||||||
|
speed_print = 45
|
||||||
layer_height = 0.1
|
layer_height = 0.1
|
||||||
layer_height_0 = 0.1
|
layer_height_0 = 0.1
|
||||||
cool_fan_enabled = True
|
cool_fan_enabled = False
|
||||||
cool_fan_full_at_height = 0.2
|
cool_fan_full_at_height = 0.2
|
||||||
cool_fan_speed = 50
|
cool_fan_speed = 50
|
||||||
cool_fan_speed_max = 50
|
cool_fan_speed_max = 50
|
||||||
|
|
|
@ -12,9 +12,10 @@ material = fabtotum_abs
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
adhesion_type = raft
|
adhesion_type = raft
|
||||||
|
speed_print = 60
|
||||||
layer_height = 0.15
|
layer_height = 0.15
|
||||||
layer_height_0 = 0.15
|
layer_height_0 = 0.15
|
||||||
cool_fan_enabled = True
|
cool_fan_enabled = False
|
||||||
cool_fan_full_at_height = 0.3
|
cool_fan_full_at_height = 0.3
|
||||||
cool_fan_speed = 50
|
cool_fan_speed = 50
|
||||||
cool_fan_speed_max = 50
|
cool_fan_speed_max = 50
|
||||||
|
|
|
@ -44,7 +44,7 @@ skirt_gap = 1.5
|
||||||
skirt_line_count = 5
|
skirt_line_count = 5
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = 25
|
speed_layer_0 = 25
|
||||||
speed_print = 50
|
speed_print = 30
|
||||||
speed_topbottom = 40
|
speed_topbottom = 40
|
||||||
speed_travel = 200
|
speed_travel = 200
|
||||||
speed_wall_0 = 40
|
speed_wall_0 = 40
|
||||||
|
|
|
@ -44,7 +44,7 @@ skirt_gap = 1.5
|
||||||
skirt_line_count = 5
|
skirt_line_count = 5
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = 25
|
speed_layer_0 = 25
|
||||||
speed_print = 50
|
speed_print = 30
|
||||||
speed_topbottom = 40
|
speed_topbottom = 40
|
||||||
speed_travel = 200
|
speed_travel = 200
|
||||||
speed_wall_0 = 40
|
speed_wall_0 = 40
|
||||||
|
|
|
@ -44,7 +44,7 @@ skirt_gap = 1.5
|
||||||
skirt_line_count = 5
|
skirt_line_count = 5
|
||||||
speed_infill = =speed_print
|
speed_infill = =speed_print
|
||||||
speed_layer_0 = 25
|
speed_layer_0 = 25
|
||||||
speed_print = 50
|
speed_print = 30
|
||||||
speed_topbottom = 40
|
speed_topbottom = 40
|
||||||
speed_travel = 200
|
speed_travel = 200
|
||||||
speed_wall_0 = 40
|
speed_wall_0 = 40
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = fabtotum_pla
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
adhesion_type = skirt
|
adhesion_type = skirt
|
||||||
|
speed_print = 80
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
layer_height_0 = 0.2
|
layer_height_0 = 0.2
|
||||||
cool_fan_enabled = True
|
cool_fan_enabled = True
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = fabtotum_pla
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
adhesion_type = skirt
|
adhesion_type = skirt
|
||||||
|
speed_print = 45
|
||||||
layer_height = 0.1
|
layer_height = 0.1
|
||||||
layer_height_0 = 0.1
|
layer_height_0 = 0.1
|
||||||
cool_fan_enabled = True
|
cool_fan_enabled = True
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = fabtotum_pla
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
adhesion_type = skirt
|
adhesion_type = skirt
|
||||||
|
speed_print = 60
|
||||||
layer_height = 0.15
|
layer_height = 0.15
|
||||||
layer_height_0 = 0.15
|
layer_height_0 = 0.15
|
||||||
cool_fan_enabled = True
|
cool_fan_enabled = True
|
||||||
|
|
25
resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg
Normal file
25
resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
definition = fabtotum
|
||||||
|
name = Fast Quality
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
setting_version = 4
|
||||||
|
material = fabtotum_tpu
|
||||||
|
quality_type = fast
|
||||||
|
weight = -1
|
||||||
|
|
||||||
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
|
speed_print = 80
|
||||||
|
layer_height = 0.2
|
||||||
|
layer_height_0 = 0.2
|
||||||
|
cool_fan_enabled = True
|
||||||
|
cool_fan_full_at_height = 0.4
|
||||||
|
cool_fan_speed = 100
|
||||||
|
cool_fan_speed_max = 100
|
||||||
|
cool_fan_speed_min = 100
|
||||||
|
cool_min_layer_time = 5
|
||||||
|
cool_min_speed = 20
|
||||||
|
|
24
resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg
Normal file
24
resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
definition = fabtotum
|
||||||
|
name = High Quality
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
setting_version = 4
|
||||||
|
material = fabtotum_tpu
|
||||||
|
quality_type = high
|
||||||
|
weight = 1
|
||||||
|
|
||||||
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
|
layer_height = 0.1
|
||||||
|
layer_height_0 = 0.1
|
||||||
|
cool_fan_enabled = True
|
||||||
|
cool_fan_full_at_height = 0.2
|
||||||
|
cool_fan_speed = 100
|
||||||
|
cool_fan_speed_max = 100
|
||||||
|
cool_fan_speed_min = 100
|
||||||
|
cool_min_layer_time = 5
|
||||||
|
cool_min_speed = 20
|
||||||
|
|
25
resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg
Normal file
25
resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
definition = fabtotum
|
||||||
|
name = Normal Quality
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
setting_version = 4
|
||||||
|
material = fabtotum_TPU
|
||||||
|
quality_type = normal
|
||||||
|
weight = 0
|
||||||
|
|
||||||
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
|
speed_print = 80
|
||||||
|
layer_height = 0.15
|
||||||
|
layer_height_0 = 0.15
|
||||||
|
cool_fan_enabled = True
|
||||||
|
cool_fan_full_at_height = 0.3
|
||||||
|
cool_fan_speed = 100
|
||||||
|
cool_fan_speed_max = 100
|
||||||
|
cool_fan_speed_min = 100
|
||||||
|
cool_min_layer_time = 5
|
||||||
|
cool_min_speed = 20
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_petg
|
||||||
variant = 0.4 mm
|
variant = 0.4 mm
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_petg
|
||||||
variant = 0.4 mm 2-fans
|
variant = 0.4 mm 2-fans
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_petg
|
||||||
variant = 0.4 mm
|
variant = 0.4 mm
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_petg
|
||||||
variant = 0.4 mm 2-fans
|
variant = 0.4 mm 2-fans
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_pla
|
||||||
variant = 0.4 mm
|
variant = 0.4 mm
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_pla
|
||||||
variant = 0.4 mm 2-fans
|
variant = 0.4 mm 2-fans
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_pla
|
||||||
variant = 0.4 mm
|
variant = 0.4 mm
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_pla
|
||||||
variant = 0.4 mm 2-fans
|
variant = 0.4 mm 2-fans
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_pla
|
||||||
variant = 0.4 mm
|
variant = 0.4 mm
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_pla
|
||||||
variant = 0.4 mm 2-fans
|
variant = 0.4 mm 2-fans
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -12,6 +12,7 @@ material = generic_pla
|
||||||
variant = 0.4 mm
|
variant = 0.4 mm
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
|
adhesion_type = skirt
|
||||||
bottom_thickness = 0.6
|
bottom_thickness = 0.6
|
||||||
coasting_enable = True
|
coasting_enable = True
|
||||||
coasting_speed = 95
|
coasting_speed = 95
|
||||||
|
|
|
@ -45,7 +45,7 @@ retraction_extrusion_window = 1
|
||||||
retraction_hop = 1.5
|
retraction_hop = 1.5
|
||||||
retraction_hop_enabled = True
|
retraction_hop_enabled = True
|
||||||
retraction_hop_only_when_collides = True
|
retraction_hop_only_when_collides = True
|
||||||
retraction_min_travel = 0.8
|
retraction_min_travel = =line_width * 2
|
||||||
retraction_prime_speed = 15
|
retraction_prime_speed = 15
|
||||||
skin_overlap = 5
|
skin_overlap = 5
|
||||||
speed_equalize_flow_enabled = True
|
speed_equalize_flow_enabled = True
|
||||||
|
|
|
@ -46,7 +46,7 @@ retraction_extrusion_window = 1
|
||||||
retraction_hop = 1.5
|
retraction_hop = 1.5
|
||||||
retraction_hop_enabled = True
|
retraction_hop_enabled = True
|
||||||
retraction_hop_only_when_collides = True
|
retraction_hop_only_when_collides = True
|
||||||
retraction_min_travel = 0.8
|
retraction_min_travel = =line_width * 2
|
||||||
retraction_prime_speed = 15
|
retraction_prime_speed = 15
|
||||||
skin_overlap = 5
|
skin_overlap = 5
|
||||||
speed_equalize_flow_enabled = True
|
speed_equalize_flow_enabled = True
|
||||||
|
|
|
@ -43,7 +43,7 @@ retraction_extrusion_window = 1
|
||||||
retraction_hop = 1.5
|
retraction_hop = 1.5
|
||||||
retraction_hop_enabled = True
|
retraction_hop_enabled = True
|
||||||
retraction_hop_only_when_collides = True
|
retraction_hop_only_when_collides = True
|
||||||
retraction_min_travel = 0.8
|
retraction_min_travel = =line_width * 2
|
||||||
retraction_prime_speed = 15
|
retraction_prime_speed = 15
|
||||||
skin_overlap = 5
|
skin_overlap = 5
|
||||||
speed_equalize_flow_enabled = True
|
speed_equalize_flow_enabled = True
|
||||||
|
|
|
@ -41,7 +41,7 @@ retraction_count_max = 12
|
||||||
retraction_extra_prime_amount = 0.5
|
retraction_extra_prime_amount = 0.5
|
||||||
retraction_hop = 1.5
|
retraction_hop = 1.5
|
||||||
retraction_hop_only_when_collides = False
|
retraction_hop_only_when_collides = False
|
||||||
retraction_min_travel = 0.8
|
retraction_min_travel = =line_width * 2
|
||||||
retraction_prime_speed = 15
|
retraction_prime_speed = 15
|
||||||
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
||||||
speed_print = 30
|
speed_print = 30
|
||||||
|
|
|
@ -42,7 +42,7 @@ retraction_count_max = 12
|
||||||
retraction_extra_prime_amount = 0.5
|
retraction_extra_prime_amount = 0.5
|
||||||
retraction_hop = 1.5
|
retraction_hop = 1.5
|
||||||
retraction_hop_only_when_collides = False
|
retraction_hop_only_when_collides = False
|
||||||
retraction_min_travel = 0.8
|
retraction_min_travel = =line_width * 2
|
||||||
retraction_prime_speed = 15
|
retraction_prime_speed = 15
|
||||||
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
||||||
speed_print = 30
|
speed_print = 30
|
||||||
|
|
|
@ -41,7 +41,7 @@ retraction_count_max = 12
|
||||||
retraction_extra_prime_amount = 0.5
|
retraction_extra_prime_amount = 0.5
|
||||||
retraction_hop = 1.5
|
retraction_hop = 1.5
|
||||||
retraction_hop_only_when_collides = False
|
retraction_hop_only_when_collides = False
|
||||||
retraction_min_travel = 0.8
|
retraction_min_travel = =line_width * 2
|
||||||
retraction_prime_speed = 15
|
retraction_prime_speed = 15
|
||||||
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
||||||
speed_print = 30
|
speed_print = 30
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = 2
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
author = Cartesio
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
type = variant
|
type = variant
|
||||||
hardware_type = nozzle
|
hardware_type = nozzle
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = 2
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
author = Cartesio
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
type = variant
|
type = variant
|
||||||
hardware_type = nozzle
|
hardware_type = nozzle
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = 2
|
||||||
definition = cartesio
|
definition = cartesio
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
author = Cartesio
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
type = variant
|
type = variant
|
||||||
hardware_type = nozzle
|
hardware_type = nozzle
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = 2
|
||||||
definition = fabtotum
|
definition = fabtotum
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
author = FABtotum
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
type = variant
|
type = variant
|
||||||
hardware_type = nozzle
|
hardware_type = nozzle
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = 2
|
||||||
definition = fabtotum
|
definition = fabtotum
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
author = FABtotum
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
type = variant
|
type = variant
|
||||||
hardware_type = nozzle
|
hardware_type = nozzle
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = 2
|
||||||
definition = fabtotum
|
definition = fabtotum
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
author = FABtotum
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
type = variant
|
type = variant
|
||||||
hardware_type = nozzle
|
hardware_type = nozzle
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue