Merge remote-tracking branch 'refs/remotes/Ultimaker/master'

This commit is contained in:
Thomas Karl Pietrowski 2016-06-10 13:46:25 +02:00
commit 6c158ba845
35 changed files with 403 additions and 155 deletions

View 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

View File

@ -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())

View File

@ -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())

View File

@ -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)

View File

@ -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:

View File

@ -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.

View File

@ -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__()

View File

@ -61,7 +61,7 @@ Item {
onLoaded: {
settingLoader.item.showRevertButton = false
settingLoader.item.showInheritButton = false
settingLoader.item.doDepthIdentation = false
settingLoader.item.doDepthIndentation = false
}
sourceComponent:

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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.
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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