Merge branch 'master' into fix_tests_cura_engine_backend

This commit is contained in:
Ian Paschal 2018-07-06 09:48:07 +02:00 committed by GitHub
commit 75d5828f5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 119 additions and 54 deletions

View file

@ -1,12 +1,13 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import io import io
import os import os
import re import re
import shutil import shutil
from typing import Optional from typing import Dict, Optional
from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile
from UM import i18nCatalog from UM import i18nCatalog
@ -28,9 +29,9 @@ class Backup:
# Re-use translation catalog. # Re-use translation catalog.
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
def __init__(self, zip_file: bytes = None, meta_data: dict = None) -> None: def __init__(self, zip_file: bytes = None, meta_data: Dict[str, str] = None) -> None:
self.zip_file = zip_file # type: Optional[bytes] self.zip_file = zip_file # type: Optional[bytes]
self.meta_data = meta_data # type: Optional[dict] self.meta_data = meta_data # type: Optional[Dict[str, str]]
## Create a back-up from the current user config folder. ## Create a back-up from the current user config folder.
def makeFromCurrent(self) -> None: def makeFromCurrent(self) -> None:

View file

@ -1,6 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional, Tuple
from typing import Dict, Optional, Tuple
from UM.Logger import Logger from UM.Logger import Logger
from cura.Backups.Backup import Backup from cura.Backups.Backup import Backup
@ -18,7 +19,7 @@ class BackupsManager:
## Get a back-up of the current configuration. ## Get a back-up of the current configuration.
# \return A tuple containing a ZipFile (the actual back-up) and a dict # \return A tuple containing a ZipFile (the actual back-up) and a dict
# containing some metadata (like version). # containing some metadata (like version).
def createBackup(self) -> Tuple[Optional[bytes], Optional[dict]]: def createBackup(self) -> Tuple[Optional[bytes], Optional[Dict[str, str]]]:
self._disableAutoSave() self._disableAutoSave()
backup = Backup() backup = Backup()
backup.makeFromCurrent() backup.makeFromCurrent()
@ -30,7 +31,7 @@ class BackupsManager:
# \param zip_file A bytes object containing the actual back-up. # \param zip_file A bytes object containing the actual back-up.
# \param meta_data A dict containing some metadata that is needed to # \param meta_data A dict containing some metadata that is needed to
# restore the back-up correctly. # restore the back-up correctly.
def restoreBackup(self, zip_file: bytes, meta_data: dict) -> None: def restoreBackup(self, zip_file: bytes, meta_data: Dict[str, str]) -> None:
if not meta_data.get("cura_release", None): if not meta_data.get("cura_release", None):
# If there is no "cura_release" specified in the meta data, we don't execute a backup restore. # If there is no "cura_release" specified in the meta data, we don't execute a backup restore.
Logger.log("w", "Tried to restore a backup without specifying a Cura version number.") Logger.log("w", "Tried to restore a backup without specifying a Cura version number.")
@ -43,13 +44,13 @@ class BackupsManager:
if restored: if restored:
# At this point, Cura will need to restart for the changes to take effect. # At this point, Cura will need to restart for the changes to take effect.
# We don't want to store the data at this point as that would override the just-restored backup. # We don't want to store the data at this point as that would override the just-restored backup.
self._application.windowClosed(save_data=False) self._application.windowClosed(save_data = False)
## Here we try to disable the auto-save plug-in as it might interfere with ## Here we try to disable the auto-save plug-in as it might interfere with
# restoring a back-up. # restoring a back-up.
def _disableAutoSave(self): def _disableAutoSave(self) -> None:
self._application.setSaveDataEnabled(False) self._application.setSaveDataEnabled(False)
## Re-enable auto-save after we're done. ## Re-enable auto-save after we're done.
def _enableAutoSave(self): def _enableAutoSave(self) -> None:
self._application.setSaveDataEnabled(True) self._application.setSaveDataEnabled(True)

View file

@ -47,10 +47,10 @@ class BuildVolume(SceneNode):
self._disallowed_area_color = None self._disallowed_area_color = None
self._error_area_color = None self._error_area_color = None
self._width = 0 self._width = 0 #type: float
self._height = 0 self._height = 0 #type: float
self._depth = 0 self._depth = 0 #type: float
self._shape = "" self._shape = "" #type: str
self._shader = None self._shader = None
@ -154,19 +154,19 @@ class BuildVolume(SceneNode):
if active_extruder_changed is not None: if active_extruder_changed is not None:
active_extruder_changed.connect(self._updateDisallowedAreasAndRebuild) active_extruder_changed.connect(self._updateDisallowedAreasAndRebuild)
def setWidth(self, width): def setWidth(self, width: float) -> None:
if width is not None: if width is not None:
self._width = width self._width = width
def setHeight(self, height): def setHeight(self, height: float) -> None:
if height is not None: if height is not None:
self._height = height self._height = height
def setDepth(self, depth): def setDepth(self, depth: float) -> None:
if depth is not None: if depth is not None:
self._depth = depth self._depth = depth
def setShape(self, shape: str): def setShape(self, shape: str) -> None:
if shape: if shape:
self._shape = shape self._shape = shape
@ -294,7 +294,7 @@ class BuildVolume(SceneNode):
if not self._width or not self._height or not self._depth: if not self._width or not self._height or not self._depth:
return return
if not self._application._qml_engine: if not self._engine_ready:
return return
if not self._volume_outline_color: if not self._volume_outline_color:

View file

@ -12,14 +12,14 @@ from UM.Platform import Platform
parser = argparse.ArgumentParser(prog = "cura", parser = argparse.ArgumentParser(prog = "cura",
add_help = False) add_help = False)
parser.add_argument('--debug', parser.add_argument("--debug",
action='store_true', action="store_true",
default = False, default = False,
help = "Turn on the debug mode by setting this option." help = "Turn on the debug mode by setting this option."
) )
parser.add_argument('--trigger-early-crash', parser.add_argument("--trigger-early-crash",
dest = 'trigger_early_crash', dest = "trigger_early_crash",
action = 'store_true', action = "store_true",
default = False, default = False,
help = "FOR TESTING ONLY. Trigger an early crash to show the crash dialog." help = "FOR TESTING ONLY. Trigger an early crash to show the crash dialog."
) )

View file

@ -287,7 +287,9 @@ class FlavorParser:
# We obtain the filament diameter from the selected extruder to calculate line widths # We obtain the filament diameter from the selected extruder to calculate line widths
global_stack = CuraApplication.getInstance().getGlobalContainerStack() global_stack = CuraApplication.getInstance().getGlobalContainerStack()
if global_stack: if not global_stack:
return None
self._filament_diameter = global_stack.extruders[str(self._extruder_number)].getProperty("material_diameter", "value") self._filament_diameter = global_stack.extruders[str(self._extruder_number)].getProperty("material_diameter", "value")
scene_node = CuraSceneNode() scene_node = CuraSceneNode()

View file

@ -247,57 +247,57 @@ class PauseAtHeight(Script):
prepend_gcode += ";added code by post processing\n" prepend_gcode += ";added code by post processing\n"
prepend_gcode += ";script: PauseAtHeight.py\n" prepend_gcode += ";script: PauseAtHeight.py\n"
if pause_at == "height": if pause_at == "height":
prepend_gcode += ";current z: {z}\n".format(z=current_z) prepend_gcode += ";current z: {z}\n".format(z = current_z)
prepend_gcode += ";current height: {height}\n".format(height=current_height) prepend_gcode += ";current height: {height}\n".format(height = current_height)
else: else:
prepend_gcode += ";current layer: {layer}\n".format(layer=current_layer) prepend_gcode += ";current layer: {layer}\n".format(layer = current_layer)
# Retraction # Retraction
prepend_gcode += self.putValue(M=83) + "\n" prepend_gcode += self.putValue(M = 83) + "\n"
if retraction_amount != 0: if retraction_amount != 0:
prepend_gcode += self.putValue(G=1, E=-retraction_amount, F=retraction_speed * 60) + "\n" prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n"
# Move the head away # Move the head away
prepend_gcode += self.putValue(G=1, Z=current_z + 1, F=300) + "\n" prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n"
# This line should be ok # This line should be ok
prepend_gcode += self.putValue(G=1, X=park_x, Y=park_y, F=9000) + "\n" prepend_gcode += self.putValue(G = 1, X = park_x, Y = park_y, F = 9000) + "\n"
if current_z < 15: if current_z < 15:
prepend_gcode += self.putValue(G=1, Z=15, F=300) + "\n" prepend_gcode += self.putValue(G = 1, Z = 15, F = 300) + "\n"
# Set extruder standby temperature # Set extruder standby temperature
prepend_gcode += self.putValue(M=104, S=standby_temperature) + "; standby temperature\n" prepend_gcode += self.putValue(M = 104, S = standby_temperature) + "; standby temperature\n"
# Wait till the user continues printing # Wait till the user continues printing
prepend_gcode += self.putValue(M=0) + ";Do the actual pause\n" prepend_gcode += self.putValue(M = 0) + ";Do the actual pause\n"
# Set extruder resume temperature # Set extruder resume temperature
prepend_gcode += self.putValue(M = 109, S = int(target_temperature.get(current_t, 0))) + "; resume temperature\n" prepend_gcode += self.putValue(M = 109, S = int(target_temperature.get(current_t, 0))) + "; resume temperature\n"
# Push the filament back, # Push the filament back,
if retraction_amount != 0: if retraction_amount != 0:
prepend_gcode += self.putValue(G=1, E=retraction_amount, F=retraction_speed * 60) + "\n" prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n"
# Optionally extrude material # Optionally extrude material
if extrude_amount != 0: if extrude_amount != 0:
prepend_gcode += self.putValue(G=1, E=extrude_amount, F=extrude_speed * 60) + "\n" prepend_gcode += self.putValue(G = 1, E = extrude_amount, F = extrude_speed * 60) + "\n"
# and retract again, the properly primes the nozzle # and retract again, the properly primes the nozzle
# when changing filament. # when changing filament.
if retraction_amount != 0: if retraction_amount != 0:
prepend_gcode += self.putValue(G=1, E=-retraction_amount, F=retraction_speed * 60) + "\n" prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n"
# Move the head back # Move the head back
prepend_gcode += self.putValue(G=1, Z=current_z + 1, F=300) + "\n" prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n"
prepend_gcode += self.putValue(G=1, X=x, Y=y, F=9000) + "\n" prepend_gcode += self.putValue(G = 1, X = x, Y = y, F = 9000) + "\n"
if retraction_amount != 0: if retraction_amount != 0:
prepend_gcode += self.putValue(G=1, E=retraction_amount, F=retraction_speed * 60) + "\n" prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n"
prepend_gcode += self.putValue(G=1, F=9000) + "\n" prepend_gcode += self.putValue(G = 1, F = 9000) + "\n"
prepend_gcode += self.putValue(M=82) + "\n" prepend_gcode += self.putValue(M = 82) + "\n"
# reset extrude value to pre pause value # reset extrude value to pre pause value
prepend_gcode += self.putValue(G=92, E=current_e) + "\n" prepend_gcode += self.putValue(G = 92, E = current_e) + "\n"
layer = prepend_gcode + layer layer = prepend_gcode + layer

View file

@ -76,11 +76,26 @@ Item
} }
} }
Component
{
id: columnTextDelegate
Label
{
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
text: styleData.value || ""
elide: Text.ElideRight
color: UM.Theme.getColor("text_medium")
font: UM.Theme.getFont("default")
}
}
TableViewColumn TableViewColumn
{ {
role: "machine" role: "machine"
title: "Machine" title: "Machine"
width: Math.floor(table.width * 0.25) width: Math.floor(table.width * 0.25)
delegate: columnTextDelegate
} }
TableViewColumn TableViewColumn
{ {

View file

@ -15,6 +15,7 @@ Item
Label Label
{ {
text: catalog.i18nc("@info", "You will need to restart Cura before changes in packages have effect.") text: catalog.i18nc("@info", "You will need to restart Cura before changes in packages have effect.")
color: UM.Theme.getColor("text")
height: Math.floor(UM.Theme.getSize("toolbox_footer_button").height) height: Math.floor(UM.Theme.getSize("toolbox_footer_button").height)
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
anchors anchors
@ -25,7 +26,7 @@ Item
right: restartButton.right right: restartButton.right
rightMargin: UM.Theme.getSize("default_margin").width rightMargin: UM.Theme.getSize("default_margin").width
} }
color: UM.Theme.getColor("text")
} }
Button Button
{ {

View file

@ -224,6 +224,11 @@ class Toolbox(QObject, Extension):
if not self._dialog: if not self._dialog:
self._dialog = self._createDialog("Toolbox.qml") self._dialog = self._createDialog("Toolbox.qml")
if not self._dialog:
Logger.log("e", "Unexpected error trying to create the 'Toolbox' dialog.")
return
self._dialog.show() self._dialog.show()
# Apply enabled/disabled state to installed plugins # Apply enabled/disabled state to installed plugins
@ -231,9 +236,11 @@ class Toolbox(QObject, Extension):
def _createDialog(self, qml_name: str) -> QObject: def _createDialog(self, qml_name: str) -> QObject:
Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name) Logger.log("d", "Toolbox: Creating dialog [%s].", qml_name)
path = os.path.join(cast(str, PluginRegistry.getInstance().getPluginPath(self.getPluginId())), "resources", "qml", qml_name) plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if not path: if not plugin_path:
raise Exception("Failed to create toolbox QML path") return None
path = os.path.join(plugin_path, "resources", "qml", qml_name)
dialog = self._application.createQmlComponent(path, {"toolbox": self}) dialog = self._application.createQmlComponent(path, {"toolbox": self})
if not dialog: if not dialog:
raise Exception("Failed to create toolbox dialog") raise Exception("Failed to create toolbox dialog")

View file

@ -128,6 +128,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
else: else:
writer = CuraApplication.getInstance().getMeshFileHandler().getWriterByMimeType(cast(str, preferred_format["mime_type"])) writer = CuraApplication.getInstance().getMeshFileHandler().getWriterByMimeType(cast(str, preferred_format["mime_type"]))
if not writer:
Logger.log("e", "Unexpected error when trying to get the FileWriter")
return
#This function pauses with the yield, waiting on instructions on which printer it needs to print with. #This function pauses with the yield, waiting on instructions on which printer it needs to print with.
if not writer: if not writer:
Logger.log("e", "Missing file or mesh writer!") Logger.log("e", "Missing file or mesh writer!")

View file

@ -170,11 +170,10 @@ class DiscoverUM3Action(MachineAction):
Logger.log("d", "Creating additional ui components for UM3.") Logger.log("d", "Creating additional ui components for UM3.")
# Create networking dialog # Create networking dialog
path = os.path.join(cast(str, PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting")), "UM3InfoComponents.qml") plugin_path = PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting")
if not path: if not plugin_path:
Logger.log("w", "Could not get QML path for UM3 network printing UI.")
return return
path = os.path.join(plugin_path, "UM3InfoComponents.qml")
self.__additional_components_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self}) self.__additional_components_view = CuraApplication.getInstance().createQmlComponent(path, {"manager": self})
if not self.__additional_components_view: if not self.__additional_components_view:
Logger.log("w", "Could not create ui components for UM3.") Logger.log("w", "Could not create ui components for UM3.")

View file

@ -0,0 +1,35 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import configparser #To parse the resulting config files.
import pytest #To register tests with.
import VersionUpgrade34to40 #The module we're testing.
## Creates an instance of the upgrader to test with.
@pytest.fixture
def upgrader():
return VersionUpgrade34to40.VersionUpgrade34to40()
test_upgrade_version_nr_data = [
("Empty config file",
"""[general]
version = 5
[metadata]
setting_version = 4
"""
)
]
## Tests whether the version numbers are updated.
@pytest.mark.parametrize("test_name, file_data", test_upgrade_version_nr_data)
def test_upgradeVersionNr(test_name, file_data, upgrader):
#Perform the upgrade.
_, upgraded_instances = upgrader.upgradePreferences(file_data, "<string>")
upgraded_instance = upgraded_instances[0]
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(upgraded_instance)
#Check the new version.
assert parser["general"]["version"] == "6"
assert parser["metadata"]["setting_version"] == "5"

View file

@ -2,6 +2,7 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from math import pi, sin, cos, sqrt from math import pi, sin, cos, sqrt
from typing import Dict
import numpy import numpy
@ -42,8 +43,7 @@ class X3DReader(MeshReader):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
self._supported_extensions = [".x3d"] self._supported_extensions = [".x3d"]
# TODO: Remove after testing because it appears to be unused self._namespaces = {} # type: Dict[str, str]
# self._namespaces = {}
# Main entry point # Main entry point
# Reads the file, returns a SceneNode (possibly with nested ones), or None # Reads the file, returns a SceneNode (possibly with nested ones), or None