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

This commit is contained in:
Ghostkeeper 2017-05-10 11:40:24 +02:00
commit 1a96cdfdb7
No known key found for this signature in database
GPG Key ID: C5F96EE2BC0F7E75
4 changed files with 78 additions and 62 deletions

View File

@ -1,11 +1,11 @@
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, pyqtSlot
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
import UM.Qt.ListModel
from UM.Application import Application
import UM.FlameProfiler
from cura.Settings.ExtruderManager import ExtruderManager
## Model that holds extruders.
@ -58,6 +58,11 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
self.addRoleName(self.MaterialRole, "material")
self.addRoleName(self.VariantRole, "variant")
self._update_extruder_timer = QTimer()
self._update_extruder_timer.setInterval(250)
self._update_extruder_timer.setSingleShot(True)
self._update_extruder_timer.timeout.connect(self.__updateExtruders)
self._add_global = False
self._simple_names = False
@ -111,17 +116,21 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
active_extruder_stack.containersChanged.connect(self._onExtruderStackContainersChanged)
self._active_extruder_stack = active_extruder_stack
def _onExtruderStackContainersChanged(self, container):
# The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
self._updateExtruders()
if container.getMetaDataEntry("type") == "material":
# The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
self._updateExtruders()
modelChanged = pyqtSignal()
def _updateExtruders(self):
self._update_extruder_timer.start()
## Update the list of extruders.
#
# This should be called whenever the list of extruders changes.
def _updateExtruders(self):
@UM.FlameProfiler.profile
def __updateExtruders(self):
changed = False
if self.rowCount() != 0:
@ -132,7 +141,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
if self._add_global:
material = global_container_stack.findContainer({ "type": "material" })
material = global_container_stack.material
color = material.getMetaDataEntry("color_code", default = self.defaultColors[0]) if material else self.defaultColors[0]
item = {
"id": global_container_stack.getId(),
@ -147,9 +156,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value")
manager = ExtruderManager.getInstance()
for extruder in manager.getMachineExtruders(global_container_stack.getId()):
extruder_name = extruder.getName()
material = extruder.findContainer({ "type": "material" })
variant = extruder.findContainer({"type": "variant"})
position = extruder.getMetaDataEntry("position", default = "0") # Get the position
try:
position = int(position)
@ -157,6 +163,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
position = -1
if position >= machine_extruder_count:
continue
extruder_name = extruder.getName()
material = extruder.material
variant = extruder.variant
default_color = self.defaultColors[position] if position >= 0 and position < len(self.defaultColors) else self.defaultColors[0]
color = material.getMetaDataEntry("color_code", default = default_color) if material else default_color

View File

@ -20,6 +20,7 @@ from UM.Settings.SettingDefinition import SettingDefinition
from UM.Settings.SettingFunction import SettingFunction
from UM.Settings.Validator import ValidatorState
from UM.Signal import postponeSignals
import UM.FlameProfiler
from cura.QualityManager import QualityManager
from cura.PrinterOutputDevice import PrinterOutputDevice
@ -810,13 +811,13 @@ class MachineManager(QObject):
# Quality profile come in two flavours: type=quality and type=quality_changes
# If we found a quality_changes profile then look up its parent quality profile.
container_type = containers[0].getMetaDataEntry("type")
quality_name = containers[0].getName()
quality_type = containers[0].getMetaDataEntry("quality_type")
# Get quality container and optionally the quality_changes container.
if container_type == "quality":
quality_type = containers[0].getMetaDataEntry("quality_type")
new_quality_settings_list = self.determineQualityAndQualityChangesForQualityType(quality_type)
elif container_type == "quality_changes":
quality_name = containers[0].getName()
new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name)
else:
Logger.log("e", "Tried to set quality to a container that is not of the right type")
@ -855,6 +856,7 @@ class MachineManager(QObject):
#
# \param quality_name \type{str} the name of the quality.
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
@UM.FlameProfiler.profile
def determineQualityAndQualityChangesForQualityType(self, quality_type):
quality_manager = QualityManager.getInstance()
result = []
@ -952,12 +954,16 @@ class MachineManager(QObject):
# Disconnect the signal handling from the old container.
container_type = container.getMetaDataEntry("type")
if container_type == "quality":
if stack.quality == container:
return # Nothing to do
stack.quality.nameChanged.disconnect(self._onQualityNameChanged)
stack.setQuality(container)
stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged)
elif container_type == "quality_changes" or container_type is None:
# If the container is an empty container, we need to change the quality_changes.
# Quality can never be set to empty.
if stack.qualityChanges == container:
return # Nothing to do
stack.qualityChanges.nameChanged.disconnect(self._onQualityNameChanged)
stack.setQualityChanges(container)
stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged)

View File

@ -89,7 +89,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Logger.log("w", "Unknown container stack type '%s' from %s in %s",
stack_type, file_name, project_file_name)
return global_stack_file_list, extruder_stack_file_list
if len(global_stack_file_list) != 1:
raise RuntimeError("More than one global stack file found: [%s]" % str(global_stack_file_list))
return global_stack_file_list[0], extruder_stack_file_list
## read some info so we can make decisions
# \param file_name
@ -195,12 +198,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Job.yieldThread()
# Load ContainerStack files and ExtruderStack files
container_stack_files, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(
global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(
file_name, cura_file_names)
self._resolve_strategies = {"machine": None, "quality_changes": None, "material": None}
machine_conflict = False
quality_changes_conflict = False
for container_stack_file in container_stack_files + extruder_stack_files:
for container_stack_file in [global_stack_file] + extruder_stack_files:
container_id = self._stripFileToId(container_stack_file)
serialized = archive.open(container_stack_file).read().decode("utf-8")
if machine_name == "":
@ -408,7 +411,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# Get the stack(s) saved in the workspace.
Logger.log("d", "Workspace loading is checking stacks containers...")
container_stack_files, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(file_name,
global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(file_name,
cura_file_names)
global_stack = None
@ -457,52 +460,52 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# load global stack file
try:
for container_stack_file in container_stack_files:
container_id = self._stripFileToId(container_stack_file)
container_id = self._stripFileToId(global_stack_file)
# Check if a stack by this ID already exists;
container_stacks = self._container_registry.findContainerStacks(id = container_id)
if container_stacks:
stack = container_stacks[0]
if self._resolve_strategies["machine"] == "override":
# TODO: HACK
# There is a machine, check if it has authentication data. If so, keep that data.
network_authentication_id = container_stacks[0].getMetaDataEntry("network_authentication_id")
network_authentication_key = container_stacks[0].getMetaDataEntry("network_authentication_key")
container_stacks[0].deserialize(archive.open(container_stack_file).read().decode("utf-8"))
if network_authentication_id:
container_stacks[0].addMetaDataEntry("network_authentication_id", network_authentication_id)
if network_authentication_key:
container_stacks[0].addMetaDataEntry("network_authentication_key", network_authentication_key)
elif self._resolve_strategies["machine"] == "new":
new_id = self.getNewId(container_id)
stack = GlobalStack(new_id)
stack.deserialize(archive.open(container_stack_file).read().decode("utf-8"))
# Check if a stack by this ID already exists;
container_stacks = self._container_registry.findContainerStacks(id = container_id)
if container_stacks:
stack = container_stacks[0]
# Ensure a unique ID and name
stack._id = new_id
if self._resolve_strategies["machine"] == "override":
# TODO: HACK
# There is a machine, check if it has authentication data. If so, keep that data.
network_authentication_id = container_stacks[0].getMetaDataEntry("network_authentication_id")
network_authentication_key = container_stacks[0].getMetaDataEntry("network_authentication_key")
container_stacks[0].deserialize(archive.open(global_stack_file).read().decode("utf-8"))
if network_authentication_id:
container_stacks[0].addMetaDataEntry("network_authentication_id", network_authentication_id)
if network_authentication_key:
container_stacks[0].addMetaDataEntry("network_authentication_key", network_authentication_key)
elif self._resolve_strategies["machine"] == "new":
new_id = self.getNewId(container_id)
stack = GlobalStack(new_id)
stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"))
# Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
# bound machine also needs to change.
if stack.getMetaDataEntry("machine", None):
stack.setMetaDataEntry("machine", self.getNewId(stack.getMetaDataEntry("machine")))
# Ensure a unique ID and name
stack._id = new_id
# Only machines need a new name, stacks may be non-unique
stack.setName(self._container_registry.uniqueName(stack.getName()))
container_stacks_added.append(stack)
self._container_registry.addContainer(stack)
else:
Logger.log("w", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
else:
# no existing container stack, so we create a new one
stack = GlobalStack(container_id)
# Deserialize stack by converting read data from bytes to string
stack.deserialize(archive.open(container_stack_file).read().decode("utf-8"))
# Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
# bound machine also needs to change.
if stack.getMetaDataEntry("machine", None):
stack.setMetaDataEntry("machine", self.getNewId(stack.getMetaDataEntry("machine")))
# Only machines need a new name, stacks may be non-unique
stack.setName(self._container_registry.uniqueName(stack.getName()))
container_stacks_added.append(stack)
self._container_registry.addContainer(stack)
else:
Logger.log("w", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
else:
# no existing container stack, so we create a new one
stack = GlobalStack(container_id)
# Deserialize stack by converting read data from bytes to string
stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"))
container_stacks_added.append(stack)
self._container_registry.addContainer(stack)
global_stack = stack
Job.yieldThread()
global_stack = stack
Job.yieldThread()
except:
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
# Something went really wrong. Try to remove any data that we added.
@ -585,10 +588,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# if we are reusing an existing global stack, it can already have extruders associated, so we need to remove
# them first
if global_stack.extruders:
old_extruder_stacks = global_stack.extruders
for extruder_stack in old_extruder_stacks:
self._container_registry.removeContainer(extruder_stack)
global_stack._extruders = []
for extruder_stack in global_stack.extruders:
if extruder_stack not in extruder_stacks_added: # skip new ones
self._container_registry.removeContainer(extruder_stack.getId())
for stack in extruder_stacks:
stack.setNextStack(global_stack)

View File

@ -251,7 +251,7 @@ class MachineSettingsAction(MachineAction):
if definition.getProperty("machine_gcode_flavor", "value") == "UltiGCode" and not definition.getMetaDataEntry("has_materials", False):
has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
material_container = self._global_container_stack.findContainer({"type": "material"})
material_container = self._global_container_stack.material
material_index = self._global_container_stack.getContainerIndex(material_container)
if has_materials:
@ -272,7 +272,6 @@ class MachineSettingsAction(MachineAction):
if "has_materials" in self._global_container_stack.getMetaData():
self._global_container_stack.removeMetaDataEntry("has_materials")
empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0]
self._global_container_stack.replaceContainer(material_index, empty_material)
self._global_container_stack.material = ContainerRegistry.getInstance().getEmptyInstanceContainer()
Application.getInstance().globalContainerStackChanged.emit()