mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-14 07:35:59 +08:00
Merge remote-tracking branch 'refs/remotes/Ultimaker/master'
This commit is contained in:
commit
6c158ba845
104
cura/ContainerSettingsModel.py
Normal file
104
cura/ContainerSettingsModel.py
Normal file
@ -0,0 +1,104 @@
|
||||
from UM.Application import Application
|
||||
from UM.Qt.ListModel import ListModel
|
||||
|
||||
from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QUrl
|
||||
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
||||
class ContainerSettingsModel(ListModel):
|
||||
LabelRole = Qt.UserRole + 1
|
||||
CategoryRole = Qt.UserRole + 2
|
||||
UnitRole = Qt.UserRole + 3
|
||||
ValuesRole = Qt.UserRole + 4
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
self.addRoleName(self.LabelRole, "label")
|
||||
self.addRoleName(self.CategoryRole, "category")
|
||||
self.addRoleName(self.UnitRole, "unit")
|
||||
self.addRoleName(self.ValuesRole, "values")
|
||||
|
||||
self._container_ids = []
|
||||
self._container = None
|
||||
|
||||
self._global_container_stack = None
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||
self._update()
|
||||
|
||||
def _onGlobalContainerChanged(self):
|
||||
if self._global_container_stack:
|
||||
self._global_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
|
||||
self._global_container_stack.propertyChanged.disconnect(self._onGlobalPropertyChanged)
|
||||
|
||||
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
if self._global_container_stack:
|
||||
Preferences.getInstance().setValue("cura/active_machine", self._global_container_stack.getId())
|
||||
self._global_container_stack.containersChanged.connect(self._onInstanceContainersChanged)
|
||||
self._global_container_stack.propertyChanged.connect(self._onGlobalPropertyChanged)
|
||||
|
||||
self._update()
|
||||
|
||||
def _onGlobalPropertyChanged(self, key, property_name):
|
||||
if property_name == "value":
|
||||
self._update()
|
||||
|
||||
def _onInstanceContainersChanged(self, container):
|
||||
self._update()
|
||||
|
||||
def _update(self):
|
||||
self.clear()
|
||||
|
||||
if len(self._container_ids) == 0:
|
||||
return
|
||||
|
||||
keys = []
|
||||
containers = []
|
||||
for container_id in self._container_ids:
|
||||
container = ContainerRegistry.getInstance().findContainers(id = container_id)
|
||||
if not container:
|
||||
return
|
||||
|
||||
keys = keys + list(container[0].getAllKeys())
|
||||
containers.append(container[0])
|
||||
|
||||
keys = list(set(keys))
|
||||
keys.sort()
|
||||
|
||||
for key in keys:
|
||||
definition = None
|
||||
category = None
|
||||
values = []
|
||||
for container in containers:
|
||||
|
||||
instance = container.getInstance(key)
|
||||
if instance:
|
||||
definition = instance.definition
|
||||
|
||||
# Traverse up to find the category
|
||||
category = definition
|
||||
while category.type != "category":
|
||||
category = category.parent
|
||||
|
||||
values.append(container.getProperty(key, "value"))
|
||||
else:
|
||||
values.append("")
|
||||
|
||||
self.appendItem({
|
||||
"key": key,
|
||||
"values": values,
|
||||
"label": definition.label,
|
||||
"unit": definition.unit,
|
||||
"category": category.label
|
||||
})
|
||||
|
||||
## Set the id of the container which has the settings this model should list.
|
||||
def setContainers(self, container_ids):
|
||||
self._container_ids = container_ids
|
||||
self._update()
|
||||
|
||||
containersChanged = pyqtSignal()
|
||||
@pyqtProperty("QVariantList", fset = setContainers, notify = containersChanged)
|
||||
def containers(self):
|
||||
return self.container_ids
|
@ -42,11 +42,13 @@ from . import MultiMaterialDecorator
|
||||
from . import ZOffsetDecorator
|
||||
from . import CuraSplashScreen
|
||||
from . import MachineManagerModel
|
||||
from . import ContainerSettingsModel
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
|
||||
from PyQt5.QtGui import QColor, QIcon
|
||||
from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType
|
||||
|
||||
import ast #For literal eval of extruder setting types.
|
||||
import platform
|
||||
import sys
|
||||
import os.path
|
||||
@ -92,7 +94,7 @@ class CuraApplication(QtApplication):
|
||||
|
||||
# Need to do this before ContainerRegistry tries to load the machines
|
||||
SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False)
|
||||
SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator)
|
||||
SettingDefinition.addSettingType("extruder", str, ast.literal_eval, UM.Settings.Validator)
|
||||
|
||||
super().__init__(name = "cura", version = CuraVersion, buildtype = CuraBuildType)
|
||||
|
||||
@ -351,6 +353,7 @@ class CuraApplication(QtApplication):
|
||||
|
||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
||||
|
||||
ExtruderManager.ExtruderManager.getInstance() #Initialise extruder so as to listen to global container stack changes before the first global container stack is set.
|
||||
qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager",
|
||||
MachineManagerModel.createMachineManagerModel)
|
||||
|
||||
@ -398,6 +401,8 @@ class CuraApplication(QtApplication):
|
||||
|
||||
qmlRegisterType(ExtrudersModel.ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
||||
|
||||
qmlRegisterType(ContainerSettingsModel.ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
|
||||
|
||||
qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions")
|
||||
|
||||
engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.ExtruderManager.getInstance())
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject #For communicating data and events to Qt.
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot, QObject, QVariant #For communicating data and events to Qt.
|
||||
|
||||
import UM.Application #To get the global container stack to find the current machine.
|
||||
import UM.Logger
|
||||
@ -13,7 +13,7 @@ import UM.Settings.ContainerRegistry #Finding containers by ID.
|
||||
# This keeps a list of extruder stacks for each machine.
|
||||
class ExtruderManager(QObject):
|
||||
## Signal to notify other components when the list of extruders changes.
|
||||
extrudersChanged = pyqtSignal()
|
||||
extrudersChanged = pyqtSignal(QVariant)
|
||||
|
||||
## Notify when the user switches the currently active extruder.
|
||||
activeExtruderChanged = pyqtSignal()
|
||||
@ -21,8 +21,9 @@ class ExtruderManager(QObject):
|
||||
## Registers listeners and such to listen to changes to the extruders.
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
self._extruder_trains = { } #Extruders for the current machine.
|
||||
self._extruder_trains = { } #Per machine, a dictionary of extruder container stack IDs.
|
||||
self._active_extruder_index = 0
|
||||
UM.Application.getInstance().globalContainerStackChanged.connect(self._addCurrentMachineExtruders)
|
||||
|
||||
## Gets the unique identifier of the currently active extruder stack.
|
||||
#
|
||||
@ -35,11 +36,22 @@ class ExtruderManager(QObject):
|
||||
if not UM.Application.getInstance().getGlobalContainerStack():
|
||||
return None #No active machine, so no active extruder.
|
||||
try:
|
||||
return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getId()][str(self._active_extruder_index)]
|
||||
return self._extruder_trains[UM.Application.getInstance().getGlobalContainerStack().getBottom().getId()][str(self._active_extruder_index)]
|
||||
except KeyError: #Extruder index could be -1 if the global tab is selected, or the entry doesn't exist if the machine definition is wrong.
|
||||
return None
|
||||
|
||||
## The instance of the singleton pattern.
|
||||
#
|
||||
# It's None if the extruder manager hasn't been created yet.
|
||||
__instance = None
|
||||
|
||||
## Gets an instance of the extruder manager, or creates one if no instance
|
||||
# exists yet.
|
||||
#
|
||||
# This is an implementation of singleton. If an extruder manager already
|
||||
# exists, it is re-used.
|
||||
#
|
||||
# \return The extruder manager.
|
||||
@classmethod
|
||||
def getInstance(cls):
|
||||
if not cls.__instance:
|
||||
@ -68,97 +80,129 @@ class ExtruderManager(QObject):
|
||||
for extruder_definition in container_registry.findDefinitionContainers(machine = machine_definition.getId()):
|
||||
position = extruder_definition.getMetaDataEntry("position", None)
|
||||
if not position:
|
||||
UM.Logger.Log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId())
|
||||
UM.Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.getId())
|
||||
if not container_registry.findContainerStacks(machine = machine_id, position = position): #Doesn't exist yet.
|
||||
name = container_registry.uniqueName(extruder_definition.getId()) #Make a name based on the ID of the definition.
|
||||
self.createExtruderTrain(extruder_definition, machine_definition, name, position)
|
||||
self.createExtruderTrain(extruder_definition, machine_definition, position)
|
||||
|
||||
#Gets the extruder trains that we just created as well as any that still existed.
|
||||
extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId())
|
||||
for extruder_train in extruder_trains:
|
||||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId()
|
||||
if extruder_trains:
|
||||
self.extrudersChanged.emit()
|
||||
self.extrudersChanged.emit(machine_definition)
|
||||
|
||||
## (Re)populates the collections of extruders by machine.
|
||||
def _repopulate(self):
|
||||
self._extruder_trains = { }
|
||||
if not UM.Application.getInstance().getGlobalContainerStack(): #No machine has been added yet.
|
||||
self.extrudersChanged.emit() #Yes, we just cleared the _extruders list!
|
||||
return #Then leave them empty!
|
||||
|
||||
extruder_trains = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "extruder_train")
|
||||
for extruder_train in extruder_trains:
|
||||
machine_id = extruder_train.getMetaDataEntry("machine")
|
||||
if not machine_id:
|
||||
continue
|
||||
if machine_id not in self._extruder_trains:
|
||||
self._extruder_trains[machine_id] = { }
|
||||
self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId()
|
||||
self.extrudersChanged.emit()
|
||||
|
||||
def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position):
|
||||
## Creates a container stack for an extruder train.
|
||||
#
|
||||
# The container stack has an extruder definition at the bottom, which is
|
||||
# linked to a machine definition. Then it has a nozzle profile, a material
|
||||
# profile, a quality profile and a user profile, in that order.
|
||||
#
|
||||
# The resulting container stack is added to the registry.
|
||||
#
|
||||
# \param extruder_definition The extruder to create the extruder train
|
||||
# for.
|
||||
# \param machine_definition The machine that the extruder train belongs
|
||||
# to.
|
||||
# \param position The position of this extruder train in the extruder
|
||||
# slots of the machine.
|
||||
def createExtruderTrain(self, extruder_definition, machine_definition, position):
|
||||
#Cache some things.
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
machine_id = machine_definition.getId()
|
||||
|
||||
#Create a container stack for this extruder.
|
||||
container_stack = UM.Settings.ContainerStack(extruder_train_id)
|
||||
extruder_stack_id = container_registry.uniqueName(extruder_definition.getId())
|
||||
container_stack = UM.Settings.ContainerStack(extruder_stack_id)
|
||||
container_stack.setName(extruder_definition.getName()) #Take over the display name to display the stack with.
|
||||
container_stack.addMetaDataEntry("type", "extruder_train")
|
||||
container_stack.addMetaDataEntry("machine", machine_definition.getId())
|
||||
container_stack.addMetaDataEntry("position", position)
|
||||
container_stack.addContainer(extruder_definition)
|
||||
|
||||
"""
|
||||
Yes, I'm committing this code which needs to be transformed to work later.
|
||||
#Find the nozzle to use for this extruder.
|
||||
nozzle = container_registry.getEmptyInstanceContainer()
|
||||
if definition.getMetaDataEntry("has_nozzles", default = "False") == "True":
|
||||
if len(self._nozzles) >= 1: #First add any extruder. Later, overwrite with preference if the preference is valid.
|
||||
self._nozzle = self._nozzles[0]
|
||||
preferred_nozzle_id = definition.getMetaDataEntry("preferred_nozzle")
|
||||
if machine_definition.getMetaDataEntry("has_nozzles", default = "False") == "True":
|
||||
#First add any nozzle. Later, overwrite with preference if the preference is valid.
|
||||
nozzles = container_registry.findInstanceContainers(machine = machine_id, type = "nozzle")
|
||||
if len(nozzles) >= 1:
|
||||
nozzle = nozzles[0]
|
||||
preferred_nozzle_id = machine_definition.getMetaDataEntry("preferred_nozzle")
|
||||
if preferred_nozzle_id:
|
||||
for nozzle in self._nozzles:
|
||||
if nozzle.getId() == preferred_nozzle_id:
|
||||
self._nozzle = nozzle
|
||||
break
|
||||
self._container_stack.addContainer(self._nozzle)
|
||||
preferred_nozzles = container_registry.findInstanceContainers(id = preferred_nozzle_id, type = "nozzle")
|
||||
if len(preferred_nozzles) >= 1:
|
||||
nozzle = preferred_nozzles[0]
|
||||
else:
|
||||
UM.Logger.log("w", "The preferred nozzle \"%s\" of machine %s doesn't exist or is not a nozzle profile.", preferred_nozzle_id, machine_id)
|
||||
#And leave it at the default nozzle.
|
||||
container_stack.addContainer(nozzle)
|
||||
|
||||
#Find a material to use for this nozzle.
|
||||
self._material = container_registry.getEmptyInstanceContainer()
|
||||
if self._definition.getMetaDataEntry("has_materials", default = "False") == "True":
|
||||
if self._definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True":
|
||||
all_materials = container_registry.findInstanceContainers(type = "material", nozzle = self._nozzle.getId())
|
||||
material = container_registry.getEmptyInstanceContainer()
|
||||
if machine_definition.getMetaDataEntry("has_materials", default = "False") == "True":
|
||||
#First add any material. Later, overwrite with preference if the preference is valid.
|
||||
if machine_definition.getMetaDataEntry("has_nozzle_materials", default = "False") == "True":
|
||||
materials = container_registry.findInstanceContainers(type = "material", machine = machine_id, nozzle = nozzle.getId())
|
||||
else:
|
||||
all_materials = container_registry.findInstanceContainers(type = "material")
|
||||
if len(all_materials) >= 1:
|
||||
self._material = all_materials[0]
|
||||
preferred_material_id = self._definition.getMetaDataEntry("preferred_material")
|
||||
materials = container_registry.findInstanceContainers(type = "material", machine = machine_id)
|
||||
if len(materials) >= 1:
|
||||
material = materials[0]
|
||||
preferred_material_id = machine_definition.getMetaDataEntry("preferred_material")
|
||||
if preferred_material_id:
|
||||
preferred_material = container_registry.findInstanceContainers(type = "material", id = preferred_material_id.lower())
|
||||
if len(preferred_material) >= 1:
|
||||
self._material = preferred_material[0]
|
||||
self._container_stack.addContainer(self._material)
|
||||
preferred_materials = container_registry.findInstanceContainers(id = preferred_material_id, type = "material")
|
||||
if len(preferred_materials) >= 1:
|
||||
material = preferred_materials[0]
|
||||
else:
|
||||
UM.Logger.log("w", "The preferred material \"%s\" of machine %s doesn't exist or is not a material profile.", preferred_material_id, machine_id)
|
||||
#And leave it at the default material.
|
||||
container_stack.addContainer(material)
|
||||
|
||||
#Find a quality to use for this extruder.
|
||||
self._quality = container_registry.getEmptyInstanceContainer()
|
||||
if self._definition.getMetaDataEntry("has_machine_quality"):
|
||||
all_qualities = container_registry.findInstanceContainers(type = "quality")
|
||||
if len(all_qualities) >= 1:
|
||||
self._quality = all_qualities[0]
|
||||
preferred_quality_id = self._definition.getMetaDataEntry("preferred_quality")
|
||||
quality = container_registry.getEmptyInstanceContainer()
|
||||
if machine_definition.getMetaDataEntry("has_machine_quality"):
|
||||
#First add any quality. Later, overwrite with preference if the preference is valid.
|
||||
qualities = container_registry.findInstanceContainers(type = "quality")
|
||||
if len(qualities) >= 1:
|
||||
quality = qualities[0]
|
||||
preferred_quality_id = machine_definition.getMetaDataEntry("preferred_quality")
|
||||
if preferred_quality_id:
|
||||
preferred_quality = container_registry.findInstanceContainers(type = "quality", id = preferred_quality_id.lower())
|
||||
preferred_quality = container_registry.findInstanceContainers(id = preferred_quality_id.lower(), type = "quality")
|
||||
if len(preferred_quality) >= 1:
|
||||
self._quality = preferred_quality[0]
|
||||
self._container_stack.addContainer(self._quality)
|
||||
"""
|
||||
quality = preferred_quality[0]
|
||||
else:
|
||||
UM.Logger.log("w", "The preferred quality \"%s\" of machine %s doesn't exist or is not a quality profile.", preferred_quality_id, machine_id)
|
||||
#And leave it at the default quality.
|
||||
container_stack.addContainer(quality)
|
||||
|
||||
#Add an empty user profile.
|
||||
user_profile = UM.Settings.InstanceContainer(extruder_train_id + "_current_settings")
|
||||
user_profile.addMetaDataEntry("type", "user")
|
||||
user_profile.setDefinition(machine_definition)
|
||||
user_profile = container_registry.findInstanceContainers(id = extruder_stack_id + "_current_settings")
|
||||
if user_profile: #There was already a user profile, loaded from settings.
|
||||
user_profile = user_profile[0]
|
||||
else:
|
||||
user_profile = UM.Settings.InstanceContainer(extruder_stack_id + "_current_settings") #Add an empty user profile.
|
||||
user_profile.addMetaDataEntry("type", "user")
|
||||
user_profile.setDefinition(machine_definition)
|
||||
container_registry.addContainer(user_profile)
|
||||
container_stack.addContainer(user_profile)
|
||||
container_registry.addContainer(user_profile)
|
||||
|
||||
container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
|
||||
|
||||
container_registry.addContainer(container_stack)
|
||||
|
||||
## Generates extruders for a specific machine.
|
||||
def getMachineExtruders(self, machine_definition):
|
||||
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||
machine_id = machine_definition.getId()
|
||||
if not machine_id in self._extruder_trains:
|
||||
UM.Logger.log("w", "Tried to get the extruder trains for machine %s, which doesn't exist.", machine_id)
|
||||
return
|
||||
for _,extruder_train_id in self._extruder_trains[machine_id].items():
|
||||
extruder_train = container_registry.findContainerStacks(id = extruder_train_id)
|
||||
if extruder_train:
|
||||
yield extruder_train[0]
|
||||
else:
|
||||
UM.Logger.log("w", "Machine %s refers to an extruder train with ID %s, which doesn't exist.", machine_id, extruder_train_id)
|
||||
|
||||
## Adds the extruders of the currently active machine.
|
||||
def _addCurrentMachineExtruders(self):
|
||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
if global_stack and global_stack.getBottom():
|
||||
self.addMachineExtruders(global_stack.getBottom())
|
@ -9,7 +9,8 @@ import UM.Qt.ListModel
|
||||
## Model that holds extruders.
|
||||
#
|
||||
# This model is designed for use by any list of extruders, but specifically
|
||||
# intended for drop-down lists of extruders in place of settings.
|
||||
# intended for drop-down lists of the current machine's extruders in place of
|
||||
# settings.
|
||||
class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||
## Human-readable name of the extruder.
|
||||
NameRole = Qt.UserRole + 1
|
||||
@ -37,7 +38,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||
|
||||
#Listen to changes.
|
||||
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
||||
manager.extrudersChanged.connect(self._updateExtruders)
|
||||
manager.extrudersChanged.connect(self._updateExtruders) #When the list of extruders changes in general.
|
||||
UM.Application.globalContainerStackChanged.connect(self._updateExtruders) #When the current machine changes.
|
||||
self._updateExtruders()
|
||||
|
||||
## Update the list of extruders.
|
||||
@ -46,10 +48,15 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
|
||||
def _updateExtruders(self):
|
||||
self.clear()
|
||||
manager = cura.ExtruderManager.ExtruderManager.getInstance()
|
||||
for index, extruder in enumerate(manager._extruder_trains):
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
if not global_container_stack:
|
||||
return #There is no machine to get the extruders of.
|
||||
for index, extruder in enumerate(manager.getMachineExtruders(global_container_stack.getBottom())):
|
||||
material = extruder.findContainer({ "type": "material" })
|
||||
colour = material.getMetaDataEntry("color_code", default = "#FFFF00") if material else "#FFFF00"
|
||||
item = { #Construct an item with only the relevant information.
|
||||
"name": extruder.name,
|
||||
"colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"),
|
||||
"name": extruder.getName(),
|
||||
"colour": colour,
|
||||
"index": index
|
||||
}
|
||||
self.appendItem(item)
|
||||
|
@ -36,8 +36,6 @@ class MachineManagerModel(QObject):
|
||||
|
||||
active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
|
||||
|
||||
self._active_extruder_index = 0
|
||||
|
||||
if active_machine_id != "":
|
||||
# An active machine was saved, so restore it.
|
||||
self.setActiveMachine(active_machine_id)
|
||||
@ -107,7 +105,7 @@ class MachineManagerModel(QObject):
|
||||
|
||||
@pyqtSlot(str, str)
|
||||
def addMachine(self, name, definition_id):
|
||||
definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=definition_id)
|
||||
definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = definition_id)
|
||||
if definitions:
|
||||
definition = definitions[0]
|
||||
name = self._createUniqueName("machine", "", name, definition.getName())
|
||||
@ -207,6 +205,13 @@ class MachineManagerModel(QObject):
|
||||
def isGlobalStackValid(self):
|
||||
return self._global_stack_valid
|
||||
|
||||
@pyqtProperty(str, notify = globalContainerChanged)
|
||||
def activeUserProfileId(self):
|
||||
if self._global_container_stack:
|
||||
return self._global_container_stack.getTop().getId()
|
||||
|
||||
return ""
|
||||
|
||||
@pyqtProperty(str, notify = globalContainerChanged)
|
||||
def activeMachineName(self):
|
||||
if self._global_container_stack:
|
||||
@ -429,7 +434,13 @@ class MachineManagerModel(QObject):
|
||||
def removeMachine(self, machine_id):
|
||||
# If the machine that is being removed is the currently active machine, set another machine as the active machine
|
||||
activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id)
|
||||
|
||||
current_settings_id = machine_id + "_current_settings"
|
||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = current_settings_id)
|
||||
for container in containers:
|
||||
UM.Settings.ContainerRegistry.getInstance().removeContainer(container.getId())
|
||||
UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id)
|
||||
|
||||
if activate_new_machine:
|
||||
stacks = UM.Settings.ContainerRegistry.getInstance().findContainerStacks(type = "machine")
|
||||
if stacks:
|
||||
|
@ -103,7 +103,7 @@ class ProcessSlicedLayersJob(Job):
|
||||
Job.yieldThread()
|
||||
Job.yieldThread()
|
||||
current_layer += 1
|
||||
progress = (current_layer / layer_count) * 100
|
||||
progress = (current_layer / layer_count) * 99
|
||||
# TODO: Rebuild the layer data mesh once the layer has been processed.
|
||||
# This needs some work in LayerData so we can add the new layers instead of recreating the entire mesh.
|
||||
|
||||
|
@ -10,6 +10,7 @@ from UM.Scene.Selection import Selection
|
||||
from UM.Math.Color import Color
|
||||
from UM.Mesh.MeshData import MeshData
|
||||
from UM.Job import Job
|
||||
from UM.Preferences import Preferences
|
||||
|
||||
from UM.View.RenderBatch import RenderBatch
|
||||
from UM.View.GL.OpenGL import OpenGL
|
||||
@ -41,7 +42,10 @@ class LayerView(View):
|
||||
self._top_layers_job = None
|
||||
self._activity = False
|
||||
|
||||
self._solid_layers = 1
|
||||
Preferences.getInstance().addPreference("view/top_layer_count", 1)
|
||||
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
|
||||
|
||||
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
||||
|
||||
self._top_layer_timer = QTimer()
|
||||
self._top_layer_timer.setInterval(50)
|
||||
@ -209,6 +213,16 @@ class LayerView(View):
|
||||
|
||||
self._top_layers_job = None
|
||||
|
||||
def _onPreferencesChanged(self, preference):
|
||||
if preference != "view/top_layer_count":
|
||||
return
|
||||
|
||||
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
||||
|
||||
self._current_layer_mesh = None
|
||||
self._current_layer_jumps = None
|
||||
self._top_layer_timer.start()
|
||||
|
||||
class _CreateTopLayersJob(Job):
|
||||
def __init__(self, scene, layer_number, solid_layers):
|
||||
super().__init__()
|
||||
|
@ -61,7 +61,7 @@ Item {
|
||||
onLoaded: {
|
||||
settingLoader.item.showRevertButton = false
|
||||
settingLoader.item.showInheritButton = false
|
||||
settingLoader.item.doDepthIdentation = false
|
||||
settingLoader.item.doDepthIndentation = false
|
||||
}
|
||||
|
||||
sourceComponent:
|
||||
|
@ -461,7 +461,6 @@
|
||||
"unit": "mm",
|
||||
"default_value": 0.8,
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "5",
|
||||
"minimum_value_warning": "0.6",
|
||||
"type": "float",
|
||||
"children":
|
||||
@ -891,7 +890,7 @@
|
||||
"retraction_count_max": {
|
||||
"label": "Maximum Retraction Count",
|
||||
"description": "This setting limits the number of retractions occurring within the minimum extrusion distance window. Further retractions within this window will be ignored. This avoids retracting repeatedly on the same piece of filament, as that can flatten the filament and cause grinding issues.",
|
||||
"default_value": 45,
|
||||
"default_value": 90,
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "100",
|
||||
"type": "int",
|
||||
@ -1861,7 +1860,7 @@
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 1,
|
||||
"value": "line_width",
|
||||
"value": "line_width * 2",
|
||||
"minimum_value": "0.0001",
|
||||
"maximum_value_warning": "machine_nozzle_size * 2",
|
||||
"enabled": "adhesion_type == \"raft\"",
|
||||
@ -1899,7 +1898,7 @@
|
||||
"type": "float",
|
||||
"default_value": 1,
|
||||
"minimum_value": "0.0001",
|
||||
"value": "line_width",
|
||||
"value": "line_width * 2",
|
||||
"maximum_value_warning": "machine_nozzle_size * 2",
|
||||
"enabled": "adhesion_type == \"raft\"",
|
||||
"global_only": "True"
|
||||
|
@ -93,7 +93,7 @@ UM.ManagementPage
|
||||
|
||||
Row {
|
||||
id: currentSettingsActions
|
||||
visible: base.currentItem.id == -1 || currentItem.id == Cura.MachineManager.activeQualityId
|
||||
visible: currentItem.id == Cura.MachineManager.activeQualityId
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: profileName.bottom
|
||||
@ -118,26 +118,57 @@ UM.ManagementPage
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: profileNotices
|
||||
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
Label {
|
||||
id: defaultsMessage
|
||||
visible: !currentItem.hasSettings
|
||||
text: catalog.i18nc("@action:label", "This profile has no settings and uses the defaults specified by the printer.")
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
}
|
||||
Label {
|
||||
id: noCurrentSettingsMessage
|
||||
visible: currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
id: scrollView
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : profileName.bottom
|
||||
anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
ListView {
|
||||
model: base.currentItem ? base.currentItem.settings: null
|
||||
model: Cura.ContainerSettingsModel{ containers: (currentItem.id == Cura.MachineManager.activeQualityId) ? [base.currentItem.id, Cura.MachineManager.activeUserProfileId] : [base.currentItem.id] }
|
||||
delegate: Row {
|
||||
property variant setting: model
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
Label {
|
||||
text: model.label
|
||||
elide: Text.ElideMiddle
|
||||
width: scrollView.width / 100 * 40
|
||||
}
|
||||
Label {
|
||||
text: model.value.toString()
|
||||
Repeater {
|
||||
model: setting.values.length
|
||||
Label {
|
||||
text: setting.values[index].toString()
|
||||
width: scrollView.width / 100 * 10
|
||||
font.strikeout: index < setting.values.length - 1 && setting.values[index + 1] != ""
|
||||
opacity: font.strikeout ? 0.5 : 1
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: model.unit
|
||||
|
@ -143,7 +143,7 @@ Item{
|
||||
UM.SimpleButton {
|
||||
id: customisedSettings
|
||||
|
||||
visible: UM.ActiveProfile.hasCustomisedValues
|
||||
visible: Cura.MachineManager.hasUserSettings
|
||||
height: parent.height * 0.6
|
||||
width: parent.height * 0.6
|
||||
|
||||
|
@ -20,11 +20,12 @@ Item {
|
||||
|
||||
property var showRevertButton: true
|
||||
property var showInheritButton: true
|
||||
property var doDepthIdentation: true
|
||||
property var doDepthIndentation: true
|
||||
|
||||
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
|
||||
property var state: propertyProvider.properties.state
|
||||
property var stackLevel: propertyProvider.stackLevel
|
||||
property var stackLevels: propertyProvider.stackLevels
|
||||
property var stackLevel: stackLevels[0]
|
||||
|
||||
signal contextMenuRequested()
|
||||
signal showTooltip(string text);
|
||||
@ -101,7 +102,7 @@ Item {
|
||||
id: label;
|
||||
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: doDepthIdentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0
|
||||
anchors.leftMargin: doDepthIndentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0
|
||||
anchors.right: settingControls.left;
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
@ -157,16 +158,49 @@ Item {
|
||||
{
|
||||
// This button shows when the setting has an inherited function, but is overriden by profile.
|
||||
id: inheritButton;
|
||||
|
||||
//visible: has_profile_value && base.has_inherit_function && base.is_enabled
|
||||
visible: base.state == "InstanceState.User" && base.stackLevel > 0 && base.showInheritButton
|
||||
// Inherit button needs to be visible if;
|
||||
// - User made changes that override any loaded settings
|
||||
// - This setting item uses inherit button at all
|
||||
// - The type of the value of any deeper container is an "object" (eg; is a function)
|
||||
visible:
|
||||
{
|
||||
var state = base.state == "InstanceState.User";
|
||||
var has_setting_function = false;
|
||||
for (var i = 1; i < base.stackLevels.length; i++)
|
||||
{
|
||||
has_setting_function = typeof(propertyProvider.getPropertyValue("value", base.stackLevels[i])) == "object";
|
||||
if(has_setting_function)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return state && base.showInheritButton && has_setting_function
|
||||
}
|
||||
|
||||
height: parent.height;
|
||||
width: height;
|
||||
|
||||
onClicked: {
|
||||
focus = true;
|
||||
propertyProvider.removeFromContainer(base.stackLevel)
|
||||
// Get the deepest entry of this setting that we can find. TODO: This is a bit naive, in some cases
|
||||
// there might be multiple profiles saying something about the same setting. There is no strategy
|
||||
// how to handle this as of yet.
|
||||
var last_entry = propertyProvider.stackLevels.slice(-1)[0]
|
||||
// Put that entry into the "top" instance container.
|
||||
// This ensures that the value in any of the deeper containers need not be removed, which is
|
||||
// needed for the reset button (which deletes the top value) to correctly go back to profile
|
||||
// defaults.
|
||||
if(last_entry == 4 && base.stackLevel == 0)
|
||||
{
|
||||
// Special case of the inherit reset. If only the definition (4th container) and the first
|
||||
// entry (user container) are set, we can simply remove the container.
|
||||
propertyProvider.removeFromContainer(0)
|
||||
}
|
||||
else
|
||||
{
|
||||
propertyProvider.setPropertyValue("value", propertyProvider.getPropertyValue("value", last_entry))
|
||||
propertyProvider.setPropertyValue("state", "InstanceState.Calculated")
|
||||
}
|
||||
}
|
||||
|
||||
backgroundColor: UM.Theme.getColor("setting_control");
|
||||
@ -186,6 +220,8 @@ Item {
|
||||
{
|
||||
id: controlContainer;
|
||||
|
||||
enabled: provider.isValueUsed
|
||||
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
|
@ -90,21 +90,11 @@ SettingItem
|
||||
|
||||
Keys.onReleased:
|
||||
{
|
||||
// text = text.replace(",", ".") // User convenience. We use dots for decimal values
|
||||
// if(parseFloat(text) != base.parentValue)
|
||||
// {
|
||||
// base.valueChanged(parseFloat(text));
|
||||
// }
|
||||
|
||||
propertyProvider.setPropertyValue("value", text)
|
||||
}
|
||||
|
||||
onEditingFinished:
|
||||
{
|
||||
// if(parseFloat(text) != base.parentValue)
|
||||
// {
|
||||
// base.valueChanged(parseFloat(text));
|
||||
// }
|
||||
propertyProvider.setPropertyValue("value", text)
|
||||
}
|
||||
|
||||
@ -121,33 +111,9 @@ SettingItem
|
||||
{
|
||||
target: input
|
||||
property: "text"
|
||||
value: control.format(propertyProvider.properties.value)
|
||||
value: propertyProvider.properties.value
|
||||
when: !input.activeFocus
|
||||
}
|
||||
}
|
||||
|
||||
//Rounds a floating point number to 4 decimals. This prevents floating
|
||||
//point rounding errors.
|
||||
//
|
||||
//input: The number to round.
|
||||
//decimals: The number of decimals (digits after the radix) to round to.
|
||||
//return: The rounded number.
|
||||
function roundFloat(input, decimals)
|
||||
{
|
||||
//First convert to fixed-point notation to round the number to 4 decimals and not introduce new floating point errors.
|
||||
//Then convert to a string (is implicit). The fixed-point notation will be something like "3.200".
|
||||
//Then remove any trailing zeroes and the radix.
|
||||
return input.toFixed(decimals).replace(/\.?0*$/, ""); //Match on periods, if any ( \.? ), followed by any number of zeros ( 0* ), then the end of string ( $ ).
|
||||
}
|
||||
|
||||
//Formats a value for display in the text field.
|
||||
//
|
||||
//This correctly handles formatting of float values.
|
||||
//
|
||||
//input: The string value to format.
|
||||
//return: The formatted string.
|
||||
function format(inputValue) {
|
||||
return parseFloat(inputValue) ? roundFloat(parseFloat(inputValue), 4) : inputValue //If it's a float, round to four decimals.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ ScrollView
|
||||
model: UM.SettingDefinitionsModel {
|
||||
id: definitionsModel;
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
|
||||
exclude: ["machine_settings"]
|
||||
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
|
||||
}
|
||||
|
||||
delegate: Loader
|
||||
|
@ -104,7 +104,7 @@ Item
|
||||
anchors.leftMargin: model.index * (extruderSelection.width / machineExtruderCount.properties.value)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width / machineExtruderCount.properties.value
|
||||
text: model.text
|
||||
text: model.name
|
||||
exclusiveGroup: extruderMenuGroup;
|
||||
checkable: true;
|
||||
checked: base.currentExtruderIndex == index
|
||||
@ -138,10 +138,11 @@ Item
|
||||
}
|
||||
}
|
||||
ExclusiveGroup { id: extruderMenuGroup; }
|
||||
ListView{
|
||||
ListView
|
||||
{
|
||||
id: extrudersList
|
||||
property var index: 0
|
||||
model: extrudersListModel
|
||||
model: Cura.ExtrudersModel {}
|
||||
delegate: wizardDelegate
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
@ -149,28 +150,6 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
ListModel
|
||||
{
|
||||
id: extrudersListModel
|
||||
Component.onCompleted: populateExtruderModel()
|
||||
}
|
||||
Connections
|
||||
{
|
||||
id: machineChange
|
||||
target: Cura.MachineManager
|
||||
onGlobalContainerChanged: populateExtruderModel()
|
||||
}
|
||||
|
||||
function populateExtruderModel()
|
||||
{
|
||||
extrudersListModel.clear();
|
||||
for(var extruder = 0; extruder < machineExtruderCount.properties.value ; extruder++) {
|
||||
extrudersListModel.append({
|
||||
text: catalog.i18nc("@label", "Extruder %1").arg(extruder + 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: variantRow
|
||||
anchors.top: extruderSelection.visible ? extruderSelection.bottom : machineSelectionRow.bottom
|
||||
|
@ -19,6 +19,7 @@ UM.PreferencesPage
|
||||
{
|
||||
UM.Preferences.resetPreference("view/show_overhang");
|
||||
UM.Preferences.resetPreference("view/center_on_select");
|
||||
UM.Preferences.resetPreference("view/top_layer_count");
|
||||
}
|
||||
|
||||
Column
|
||||
@ -57,12 +58,38 @@ UM.PreferencesPage
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
width: childrenRect.width;
|
||||
height: childrenRect.height;
|
||||
text: catalog.i18nc("@info:tooltip","Display 5 top layers in layer view or only the top-most layer. Rendering 5 layers takes longer, but may show more information.")
|
||||
|
||||
CheckBox
|
||||
{
|
||||
id: topLayerCheckbox
|
||||
text: catalog.i18nc("@action:button","Display five top layers in layer view.");
|
||||
checked: UM.Preferences.getValue("view/top_layer_count") == 5
|
||||
onClicked:
|
||||
{
|
||||
if(UM.Preferences.getValue("view/top_layer_count") == 5)
|
||||
{
|
||||
UM.Preferences.setValue("view/top_layer_count", 1)
|
||||
}
|
||||
else
|
||||
{
|
||||
UM.Preferences.setValue("view/top_layer_count", 5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: UM.Preferences
|
||||
onPreferenceChanged:
|
||||
{
|
||||
overhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang"))
|
||||
centerCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select"))
|
||||
topLayerCheckbox = UM.Preferences.getValue("view/top_layer_count") == 5
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ wall_thickness = 0.7
|
||||
top_bottom_thickness = 0.75
|
||||
infill_sparse_density = 18
|
||||
speed_print = 55
|
||||
speed_wall = 40
|
||||
speed_topbottom = 30
|
||||
speed_travel = 150
|
||||
speed_layer_0 = 30
|
||||
cool_min_layer_time = 3
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.72
|
||||
infill_sparse_density = 22
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 20
|
||||
cool_min_speed = 10
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 20
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 20
|
||||
cool_min_speed = 10
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.59
|
||||
top_bottom_thickness = 1.2
|
||||
infill_sparse_density = 20
|
||||
speed_print = 40
|
||||
speed_infill = 55
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 50
|
||||
cool_min_speed = 20
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 0.7
|
||||
top_bottom_thickness = 0.75
|
||||
infill_sparse_density = 18
|
||||
speed_print = 45
|
||||
speed_wall = 40
|
||||
speed_travel = 150
|
||||
speed_layer_0 = 30
|
||||
cool_min_layer_time = 3
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.72
|
||||
infill_sparse_density = 22
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 2
|
||||
cool_fan_speed_min = 80
|
||||
cool_min_speed = 15
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 20
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 80
|
||||
cool_min_speed = 10
|
||||
|
@ -15,6 +15,8 @@ wall_thickness = 0.7
|
||||
top_bottom_thickness = 0.75
|
||||
infill_sparse_density = 18
|
||||
speed_print = 60
|
||||
speed_wall = 50
|
||||
speed_topbottom = 30
|
||||
speed_travel = 150
|
||||
speed_layer_0 = 30
|
||||
cool_min_layer_time = 5
|
||||
|
@ -15,5 +15,6 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.72
|
||||
infill_sparse_density = 22
|
||||
speed_print = 50
|
||||
speed_topbottom = 20
|
||||
cool_min_layer_time = 5
|
||||
cool_min_speed = 10
|
||||
|
@ -15,5 +15,6 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 20
|
||||
speed_print = 50
|
||||
speed_topbottom = 20
|
||||
cool_min_layer_time = 5
|
||||
cool_min_speed = 10
|
||||
|
@ -15,5 +15,8 @@ wall_thickness = 1.59
|
||||
top_bottom_thickness = 1.2
|
||||
infill_sparse_density = 20
|
||||
speed_print = 55
|
||||
speed_wall = 40
|
||||
speed_wall_0 = 25
|
||||
speed_topbottom = 20
|
||||
cool_min_layer_time = 5
|
||||
cool_min_speed = 10
|
||||
|
@ -15,5 +15,6 @@ wall_thickness = 2.1
|
||||
top_bottom_thickness = 1.2
|
||||
infill_sparse_density = 20
|
||||
speed_print = 40
|
||||
speed_wall_0 = 25
|
||||
cool_min_layer_time = 5
|
||||
cool_min_speed = 10
|
||||
|
@ -15,6 +15,8 @@ wall_thickness = 0.7
|
||||
top_bottom_thickness = 0.75
|
||||
infill_sparse_density = 18
|
||||
speed_print = 55
|
||||
speed_wall = 40
|
||||
speed_topbottom = 30
|
||||
speed_travel = 150
|
||||
speed_layer_0 = 30
|
||||
cool_min_layer_time = 3
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.72
|
||||
infill_sparse_density = 22
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 20
|
||||
cool_min_speed = 10
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 20
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 20
|
||||
cool_min_speed = 10
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.59
|
||||
top_bottom_thickness = 1.2
|
||||
infill_sparse_density = 20
|
||||
speed_print = 40
|
||||
speed_infill = 55
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 50
|
||||
cool_min_speed = 20
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 0.7
|
||||
top_bottom_thickness = 0.75
|
||||
infill_sparse_density = 18
|
||||
speed_print = 45
|
||||
speed_wall = 40
|
||||
speed_travel = 150
|
||||
speed_layer_0 = 30
|
||||
cool_min_layer_time = 3
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.72
|
||||
infill_sparse_density = 22
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 2
|
||||
cool_fan_speed_min = 80
|
||||
cool_min_speed = 15
|
||||
|
@ -15,6 +15,7 @@ wall_thickness = 1.05
|
||||
top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 20
|
||||
speed_print = 45
|
||||
speed_wall = 30
|
||||
cool_min_layer_time = 3
|
||||
cool_fan_speed_min = 80
|
||||
cool_min_speed = 10
|
||||
|
Loading…
x
Reference in New Issue
Block a user