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

This commit is contained in:
Aleksei S 2018-03-29 11:54:43 +02:00
commit c81d5d9741
73 changed files with 31714 additions and 17987 deletions

View file

@ -1,10 +1,11 @@
# Copyright (c) 2017 Ultimaker B.V.
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from configparser import ConfigParser
import zipfile
import os
import threading
from typing import List, Tuple
import xml.etree.ElementTree as ET
@ -160,7 +161,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
#
# In old versions, extruder stack files have the same suffix as container stack files ".stack.cfg".
#
def _determineGlobalAndExtruderStackFiles(self, project_file_name, file_list):
def _determineGlobalAndExtruderStackFiles(self, project_file_name: str, file_list: List[str]) -> Tuple[str, List[str]]:
archive = zipfile.ZipFile(project_file_name, "r")
global_stack_file_list = [name for name in file_list if name.endswith(self._global_stack_suffix)]
@ -191,8 +192,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Logger.log("w", "Unknown container stack type '%s' from %s in %s",
stack_type, file_name, project_file_name)
if len(global_stack_file_list) != 1:
raise RuntimeError("More than one global stack file found: [%s]" % str(global_stack_file_list))
if len(global_stack_file_list) > 1:
Logger.log("e", "More than one global stack file found: [{file_list}]".format(file_list = global_stack_file_list))
#But we can recover by just getting the first global stack file.
if len(global_stack_file_list) == 0:
Logger.log("e", "No global stack file found!")
raise FileNotFoundError("No global stack file found!")
return global_stack_file_list[0], extruder_stack_file_list
@ -346,8 +351,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._machine_info.quality_changes_info = None
# Load ContainerStack files and ExtruderStack files
global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(
file_name, cura_file_names)
try:
global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(
file_name, cura_file_names)
except FileNotFoundError:
return WorkspaceReader.PreReadResult.failed
machine_conflict = False
# Because there can be cases as follows:
# - the global stack exists but some/all of the extruder stacks DON'T exist
@ -549,28 +557,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
return WorkspaceReader.PreReadResult.accepted
## Overrides an ExtruderStack in the given GlobalStack and returns the new ExtruderStack.
def _overrideExtruderStack(self, global_stack, extruder_file_content, extruder_stack_file):
# Get extruder position first
extruder_config = ConfigParser(interpolation = None)
extruder_config.read_string(extruder_file_content)
if not extruder_config.has_option("metadata", "position"):
msg = "Could not find 'metadata/position' in extruder stack file"
Logger.log("e", "Could not find 'metadata/position' in extruder stack file")
raise RuntimeError(msg)
extruder_position = extruder_config.get("metadata", "position")
try:
extruder_stack = global_stack.extruders[extruder_position]
except KeyError:
Logger.log("w", "Could not find the matching extruder stack to override for position %s", extruder_position)
return None
# Override the given extruder stack
extruder_stack.deserialize(extruder_file_content, file_name = extruder_stack_file)
# return the new ExtruderStack
return extruder_stack
## Read the project file
# Add all the definitions / materials / quality changes that do not exist yet. Then it loads
# all the stacks into the container registry. In some cases it will reuse the container for the global stack.
@ -897,7 +883,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
variant_type = VariantType.BUILD_PLATE
node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
if node is not None:
if node is not None and node.getContainer() is not None:
global_stack.variant = node.getContainer()
for position, extruder_stack in extruder_stack_dict.items():
@ -913,7 +899,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
variant_type = VariantType.NOZZLE
node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
if node is not None:
if node is not None and node.getContainer() is not None:
extruder_stack.variant = node.getContainer()
def _applyMaterials(self, global_stack, extruder_stack_dict):
@ -939,7 +925,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruder_stack.variant.getName(),
machine_material_diameter,
root_material_id)
if material_node is not None:
if material_node is not None and material_node.getContainer() is not None:
extruder_stack.material = material_node.getContainer()
def _applyChangesToMachine(self, global_stack, extruder_stack_dict):

View file

@ -210,6 +210,7 @@ class PostProcessingPlugin(QObject, Extension):
continue
script_str = script_str.replace("\\n", "\n").replace("\\\\", "\\") #Unescape escape sequences.
script_parser = configparser.ConfigParser(interpolation = None)
script_parser.optionxform = str #Don't transform the setting keys as they are case-sensitive.
script_parser.read_string(script_str)
for script_name, settings in script_parser.items(): #There should only be one, really! Otherwise we can't guarantee the order or allow multiple uses of the same script.
if script_name == "DEFAULT": #ConfigParser always has a DEFAULT section, but we don't fill it. Ignore this one.
@ -230,6 +231,7 @@ class PostProcessingPlugin(QObject, Extension):
script_list_strs = []
for script in self._script_list:
parser = configparser.ConfigParser(interpolation = None) #We'll encode the script as a config with one section. The section header is the key and its values are the settings.
parser.optionxform = str #Don't transform the setting keys as they are case-sensitive.
script_name = script.getSettingData()["key"]
parser.add_section(script_name)
for key in script.getSettingData()["settings"]:

View file

@ -12,7 +12,7 @@ Item
property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId
property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
property bool printerConnected: Cura.MachineManager.printerConnected
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
property bool authenticationRequested: printerConnected && (Cura.MachineManager.printerOutputDevices[0].authenticationState == 2 || Cura.MachineManager.printerOutputDevices[0].authenticationState == 5) // AuthState.AuthenticationRequested or AuthenticationReceived.

View file

@ -107,6 +107,8 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
Logger.log("d", "Attempting to connect with [%s]" % key)
self._discovered_devices[key].connect()
self._discovered_devices[key].connectionStateChanged.connect(self._onDeviceConnectionStateChanged)
else:
self._onDeviceConnectionStateChanged(key)
else:
if self._discovered_devices[key].isConnected():
Logger.log("d", "Attempting to close connection with [%s]" % key)
@ -117,7 +119,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
if key not in self._discovered_devices:
return
if self._discovered_devices[key].isConnected():
self.getOutputDeviceManager().addOutputDevice(self._discovered_devices[key])
# Sometimes the status changes after changing the global container and maybe the device doesn't belong to this machine
um_network_key = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("um_network_key")
if key == um_network_key:
self.getOutputDeviceManager().addOutputDevice(self._discovered_devices[key])
else:
self.getOutputDeviceManager().removeOutputDevice(key)

View file

@ -14,7 +14,7 @@ import Cura 1.0 as Cura
Cura.MachineAction
{
anchors.fill: parent;
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
property bool printerConnected: Cura.MachineManager.printerConnected
property var activeOutputDevice: printerConnected ? Cura.MachineManager.printerOutputDevices[0] : null
Item

View file

@ -71,12 +71,14 @@ class XmlMaterialProfile(InstanceContainer):
# Update the root material container
root_material_container = material_group.root_material_node.getContainer()
root_material_container.setMetaDataEntry(key, value, apply_to_all = False)
if root_material_container is not None:
root_material_container.setMetaDataEntry(key, value, apply_to_all = False)
# Update all containers derived from it
for node in material_group.derived_material_node_list:
container = node.getContainer()
container.setMetaDataEntry(key, value, apply_to_all = False)
if container is not None:
container.setMetaDataEntry(key, value, apply_to_all = False)
## Overridden from InstanceContainer, similar to setMetaDataEntry.
# without this function the setName would only set the name of the specific nozzle / material / machine combination container