Merge branch 'master' of github.com:Ultimaker/Cura

This commit is contained in:
Jaime van Kessel 2016-06-02 14:20:14 +02:00
commit 2abbb5c9a1
5 changed files with 137 additions and 21 deletions

View File

@ -18,6 +18,7 @@ from UM.JobQueue import JobQueue
from UM.SaveFile import SaveFile from UM.SaveFile import SaveFile
from UM.Scene.Selection import Selection from UM.Scene.Selection import Selection
from UM.Scene.GroupDecorator import GroupDecorator from UM.Scene.GroupDecorator import GroupDecorator
import UM.Settings.Validator
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
@ -30,7 +31,6 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from . import ExtruderManager
from . import PlatformPhysics from . import PlatformPhysics
from . import BuildVolume from . import BuildVolume
from . import CameraAnimation from . import CameraAnimation
@ -89,6 +89,7 @@ class CuraApplication(QtApplication):
# Need to do this before ContainerRegistry tries to load the machines # Need to do this before ContainerRegistry tries to load the machines
SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False) SettingDefinition.addSupportedProperty("global_only", DefinitionPropertyType.Function, default = False)
SettingDefinition.addSettingType("extruder", int, str, UM.Settings.Validator)
super().__init__(name = "cura", version = CuraVersion) super().__init__(name = "cura", version = CuraVersion)
@ -327,8 +328,6 @@ class CuraApplication(QtApplication):
qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager",
MachineManagerModel.createMachineManagerModel) MachineManagerModel.createMachineManagerModel)
self._extruder_manager = ExtruderManager.ExtruderManager()
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
self.initializeEngine() self.initializeEngine()

View File

@ -25,8 +25,8 @@ class Extruder:
self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId()) self._nozzles += container_registry.findInstanceContainers(type = "nozzle", definitions = self._definition.getId())
#Create a container stack for this extruder. #Create a container stack for this extruder.
name = self._uniqueName(self._definition.getId()) self._name = self._uniqueName(self._definition.getId())
self._container_stack = UM.Settings.ContainerStack(name) self._container_stack = UM.Settings.ContainerStack(self._name)
self._container_stack.addMetaDataEntry("type", "extruder_train") self._container_stack.addMetaDataEntry("type", "extruder_train")
self._container_stack.addContainer(self._definition) self._container_stack.addContainer(self._definition)
@ -73,15 +73,38 @@ class Extruder:
self._container_stack.addContainer(self._quality) self._container_stack.addContainer(self._quality)
#Add an empty user profile. #Add an empty user profile.
self._user_profile = UM.Settings.InstanceContainer(name + "_current_settings") self._user_profile = UM.Settings.InstanceContainer(self._name + "_current_settings")
self._user_profile.addMetaDataEntry("type", "user") self._user_profile.addMetaDataEntry("type", "user")
self._container_stack.addContainer(self._user_profile) self._container_stack.addContainer(self._user_profile)
self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack()) self._container_stack.setNextStack(UM.Application.getInstance().getGlobalContainerStack())
nozzle_changed = UM.Signal.Signal() definition_changed = UM.Signal()
material_changed = UM.Signal.Signal() material_changed = UM.Signal()
quality_changed = UM.Signal.Signal() name_changed = UM.Signal()
nozzle_changed = UM.Signal()
quality_changed = UM.Signal()
## Gets the definition container of this extruder.
#
# \return The definition container of this extruder.
@property
def definition(self):
return self._definition
## Changes the definition container of this extruder.
#
# \param value The new definition for this extruder.
@definition.setter
def definition(self, value):
try:
position = self._container_stack.index(self._definition)
except ValueError: #Definition is not in the list. Big trouble!
UM.Logger.log("e", "I've lost my old extruder definition, so I can't find where to insert the new definition.")
return
self._container_stack.replaceContainer(position, value)
self._definition = value
self.definition_changed.emit()
## Gets the currently active material on this extruder. ## Gets the currently active material on this extruder.
# #
@ -104,6 +127,22 @@ class Extruder:
self._material = value self._material = value
self.material_changed.emit() self.material_changed.emit()
## Gets the name of this extruder.
#
# \return The name of this extruder.
@property
def name(self):
return self._name
## Changes the name of this extruder.
#
# \param value The new name for this extruder.
@name.setter
def name(self, value):
self._name = value
self._container_stack.setName(value) #Also update in container stack, being defensive.
self.name_changed.emit()
## Gets the currently active nozzle on this extruder. ## Gets the currently active nozzle on this extruder.
# #
# \return The currently active nozzle on this extruder. # \return The currently active nozzle on this extruder.

View File

@ -1,13 +1,11 @@
# Copyright (c) 2016 Ultimaker B.V. # Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher. # Cura is released under the terms of the AGPLv3 or higher.
import re
from cura.Extruder import Extruder #The individual extruders managed by this manager. from cura.Extruder import Extruder #The individual extruders managed by this manager.
from UM.Application import Application #To get the global container stack to find the current machine. import UM.Application #To get the global container stack to find the current machine.
from UM.Logger import Logger import UM.Logger
from UM.Settings.ContainerStack import ContainerStack #To create container stacks for each extruder. import UM.Settings.ContainerRegistry #Finding containers by ID.
from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers by ID. import UM.Signal #To notify other components of changes in the extruders.
## Class that handles the current extruder stack. ## Class that handles the current extruder stack.
@ -16,19 +14,42 @@ from UM.Settings.ContainerRegistry import ContainerRegistry #Finding containers
# and makes sure that whenever the machine is swapped, this list is kept up to # and makes sure that whenever the machine is swapped, this list is kept up to
# date. It also contains and updates the setting stacks for the extruders. # date. It also contains and updates the setting stacks for the extruders.
class ExtruderManager: class ExtruderManager:
## The singleton instance of this manager.
__instance = None
## Signal to notify other components when the list of extruders changes.
extrudersChanged = UM.Signal()
## Registers listeners and such to listen to changes to the extruders. ## Registers listeners and such to listen to changes to the extruders.
def __init__(self): def __init__(self):
self._extruders = [] #Extruders for the current machine. self._extruders = [] #Extruders for the current machine.
self._global_container_stack = None self._global_container_stack = None
self._next_item = 0 #For when you use this class as iterator.
Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine. UM.Application.getInstance().globalContainerStackChanged.connect(self._reconnectExtruderReload) #When the current machine changes, we need to reload all extruders belonging to the new machine.
## Gets an instance of this extruder manager.
#
# If an instance was already created, the old instance is returned. This
# implements the singleton pattern.
@classmethod
def getInstance(cls):
if not cls.__instance:
cls.__instance = ExtruderManager()
return cls.__instance
## Creates an iterator over the extruders in this manager.
#
# \return An iterator over the extruders in this manager.
def __iter__(self):
return iter(self._extruders)
## When the global container stack changes, this reconnects to the new ## When the global container stack changes, this reconnects to the new
# signal for containers changing. # signal for containers changing.
def _reconnectExtruderReload(self): def _reconnectExtruderReload(self):
if self._global_container_stack: if self._global_container_stack:
self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack. self._global_container_stack.containersChanged.disconnect(self._reloadExtruders) #Disconnect from the old global container stack.
self._global_container_stack = Application.getInstance().getGlobalContainerStack() self._global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine. self._global_container_stack.containersChanged.connect(self._reloadExtruders) #When the current machine changes, we need to reload all extruders belonging to the new machine.
## (Re)loads all extruders of the currently active machine. ## (Re)loads all extruders of the currently active machine.
@ -39,15 +60,17 @@ class ExtruderManager:
def _reloadExtruders(self): def _reloadExtruders(self):
self._extruders = [] self._extruders = []
if not self._global_container_stack: #No machine has been added yet. if not self._global_container_stack: #No machine has been added yet.
self.extrudersChanged.emit() #Yes, we just cleared the _extruders list!
return #Then leave them empty! return #Then leave them empty!
#Get the extruder definitions belonging to the current machine. #Get the extruder definitions belonging to the current machine.
machine = self._global_container_stack.getBottom() machine = self._global_container_stack.getBottom()
extruder_train_ids = machine.getMetaData("machine_extruder_trains") extruder_train_ids = machine.getMetaData("machine_extruder_trains")
for extruder_train_id in extruder_train_ids: for extruder_train_id in extruder_train_ids:
extruder_definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway. extruder_definitions = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) #Should be only 1 definition if IDs are unique, but add the whole list anyway.
if not extruder_definitions: #Empty list or error. if not extruder_definitions: #Empty list or error.
Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id) UM.Logger.log("w", "Machine definition %s refers to an extruder train \"%s\", but no such extruder was found.", machine.getId(), extruder_train_id)
continue continue
for extruder_definition in extruder_definitions: for extruder_definition in extruder_definitions:
self._extruders.append(Extruder(extruder_definition)) self._extruders.append(Extruder(extruder_definition))
self.extrudersChanged.emit()

55
cura/ExtrudersModel.py Normal file
View File

@ -0,0 +1,55 @@
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from PyQt5.QtCore import Qt
import cura.ExtruderManager
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.
class ExtrudersModel(UM.Qt.ListModel):
## Human-readable name of the extruder.
NameRole = Qt.UserRole + 1
## Colour of the material loaded in the extruder.
ColourRole = Qt.UserRole + 2
## Index of the extruder, which is also the value of the setting itself.
#
# An index of 0 indicates the first extruder, an index of 1 the second
# one, and so on. This is the value that will be saved in instance
# containers.
IndexRole = Qt.UserRole + 3
## Initialises the extruders model, defining the roles and listening for
# changes in the data.
#
# \param parent Parent QtObject of this list.
def __init__(self, parent = None):
super().__init__(parent)
self.addRoleName(self.NameRole, "name")
self.addRoleName(self.ColourRole, "colour")
self.addRoleName(self.IndexRole, "index")
#Listen to changes.
manager = cura.ExtruderManager.ExtruderManager.getInstance()
manager.extrudersChanged.connect(self._updateExtruders())
## Update the list of extruders.
#
# This should be called whenever the list of extruders changes.
def _updateExtruders(self):
self.clear()
manager = cura.ExtruderManager.ExtruderManager.getInstance()
for index, extruder in enumerate(manager):
item = { #Construct an item with only the relevant information.
"name": extruder.name,
"colour": extruder.material.getMetaDataEntry("color_code", default = "#FFFF00"),
"index": index
}
self.appendItem(item)
self.sort(lambda item: item["index"])

View File

@ -48,7 +48,7 @@ ScrollView
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
//causing nasty issues when selecting differnt options. So disable asynchronous loading of enum type completely. //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
asynchronous: model.type != "enum" asynchronous: model.type != "enum"
active: model.type != undefined active: model.type != undefined