From b8cca17d46dfd00e55d4d22b0c097962158211a7 Mon Sep 17 00:00:00 2001 From: Mark Burton Date: Fri, 27 Jul 2018 10:01:16 +0100 Subject: [PATCH 01/29] Added the "Within Infill" combing option that functions identically to the original "Not in Skin" option. I've tweaked the blurb to let people know that the original behaviour is still available. --- resources/definitions/fdmprinter.def.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index e29e08228b..0352ae59fd 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -3344,13 +3344,14 @@ "retraction_combing": { "label": "Combing Mode", - "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only.", + "description": "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas and also to only comb within the infill. Note that the 'Within Infill' option behaves exactly like the 'Not in Skin' option in earlier Cura releases.", "type": "enum", "options": { "off": "Off", "all": "All", - "noskin": "Not in Skin" + "noskin": "Not in Skin", + "infill": "Within Infill" }, "default_value": "all", "resolve": "'noskin' if 'noskin' in extruderValues('retraction_combing') else ('all' if 'all' in extruderValues('retraction_combing') else 'off')", From e817d94a8310e37fd0a81b3bbbd15f9a46f97165 Mon Sep 17 00:00:00 2001 From: Matteo Spinelli Date: Thu, 2 Aug 2018 17:30:06 +0200 Subject: [PATCH 02/29] Add user editable snap distance This PR requires an update to CuraEngine as well (I'm posting the update right after) --- resources/definitions/fdmprinter.def.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index b767aac7b9..8b3e4e1f05 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5625,6 +5625,19 @@ "settable_per_mesh": false, "settable_per_extruder": true }, + "snap_distance": + { + "label": "Snap Distance", + "description": "Snap distance between polygons in mm. Controls the polygons that may be filtered out when the model is sliced. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details.", + "unit": "mm", + "type": "float", + "default_value": 1.0, + "minimum_value": "0.001", + "minimum_value_warning": "0.05", + "maximum_value_warning": "1.0", + "settable_per_mesh": true, + "settable_per_extruder": false + }, "meshfix_maximum_resolution": { "label": "Maximum Resolution", From db7f1242cd0cd028219f5ef8dfbdbc0ec039d8fb Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 14 Aug 2018 10:41:38 +0200 Subject: [PATCH 03/29] Fix some unit tests. Add fixtures to the conftest file and clean-up the code a bit. Contributes to CURA-5628 --- tests/Settings/TestCuraContainerRegistry.py | 62 +++----------------- tests/Settings/TestExtruderStack.py | 58 +++++-------------- tests/Settings/TestGlobalStack.py | 2 +- tests/Settings/conftest.py | 19 +++++++ tests/TestArrange.py | 6 +- tests/TestMachineAction.py | 63 ++++++++++----------- tests/TestProfileRequirements.py | 4 ++ tests/conftest.py | 38 +++++++++++++ 8 files changed, 118 insertions(+), 134 deletions(-) create mode 100644 tests/Settings/conftest.py create mode 100644 tests/conftest.py diff --git a/tests/Settings/TestCuraContainerRegistry.py b/tests/Settings/TestCuraContainerRegistry.py index 38b2e0f6ea..dd78f2fd68 100644 --- a/tests/Settings/TestCuraContainerRegistry.py +++ b/tests/Settings/TestCuraContainerRegistry.py @@ -1,61 +1,14 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import os #To find the directory with test files and find the test files. -import pytest #This module contains unit tests. -import shutil #To copy files to make a temporary file. import unittest.mock #To mock and monkeypatch stuff. -import urllib.parse -import copy -import cura.CuraApplication -from cura.Settings.CuraContainerRegistry import CuraContainerRegistry #The class we're testing. from cura.Settings.ExtruderStack import ExtruderStack #Testing for returning the correct types of stacks. from cura.Settings.GlobalStack import GlobalStack #Testing for returning the correct types of stacks. -from UM.Resources import Resources #Mocking some functions of this. import UM.Settings.InstanceContainer #Creating instance containers to register. import UM.Settings.ContainerRegistry #Making empty container stacks. import UM.Settings.ContainerStack #Setting the container registry here properly. -from UM.Settings.DefinitionContainer import DefinitionContainer -from UM.Settings.ContainerRegistry import ContainerRegistry - -def creteEmptyContainers(): - empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - ContainerRegistry.getInstance().addContainer(empty_variant_container) - - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - ContainerRegistry.getInstance().addContainer(empty_material_container) - - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - ContainerRegistry.getInstance().addContainer(empty_quality_container) - - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) - -## Gives a fresh CuraContainerRegistry instance. -@pytest.fixture() -def container_registry(): - registry = CuraContainerRegistry() - UM.Settings.InstanceContainer.setContainerRegistry(registry) - UM.Settings.ContainerStack.setContainerRegistry(registry) - return registry - -## Gives an arbitrary definition container. -@pytest.fixture() -def definition_container(): - return DefinitionContainer(container_id = "Test Definition") def teardown(): #If the temporary file for the legacy file rename test still exists, remove it. @@ -65,10 +18,9 @@ def teardown(): ## Tests whether addContainer properly converts to ExtruderStack. def test_addContainerExtruderStack(container_registry, definition_container): - creteEmptyContainers() container_registry.addContainer(definition_container) - container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert. + container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Extruder Stack") #A container we're going to convert. container_stack.setMetaDataEntry("type", "extruder_train") #This is now an extruder train. container_stack.insertContainer(0, definition_container) #Add a definition to it so it doesn't complain. @@ -84,7 +36,7 @@ def test_addContainerExtruderStack(container_registry, definition_container): def test_addContainerGlobalStack(container_registry, definition_container): container_registry.addContainer(definition_container) - container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert. + container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Global Stack") #A container we're going to convert. container_stack.setMetaDataEntry("type", "machine") #This is now a global stack. container_stack.insertContainer(0, definition_container) #Must have a definition. @@ -101,7 +53,7 @@ def test_addContainerGoodSettingVersion(container_registry, definition_container definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion container_registry.addContainer(definition_container) - instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") + instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance Right Version") instance.setMetaDataEntry("setting_version", CuraApplication.SettingVersion) instance.setDefinition(definition_container.getId()) @@ -116,7 +68,7 @@ def test_addContainerNoSettingVersion(container_registry, definition_container): definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion container_registry.addContainer(definition_container) - instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") + instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance No Version") #Don't add setting_version metadata. instance.setDefinition(definition_container.getId()) @@ -131,7 +83,7 @@ def test_addContainerBadSettingVersion(container_registry, definition_container) definition_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion container_registry.addContainer(definition_container) - instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance") + instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance Wrong Version") instance.setMetaDataEntry("setting_version", 9001) #Wrong version! instance.setDefinition(definition_container.getId()) @@ -174,4 +126,4 @@ def test_addContainerBadSettingVersion(container_registry, definition_container) # assert type(container) == output_class # break # else: -# assert False #Container stack with specified ID was not loaded. \ No newline at end of file +# assert False #Container stack with specified ID was not loaded. diff --git a/tests/Settings/TestExtruderStack.py b/tests/Settings/TestExtruderStack.py index 7c463fb9be..a19f99571d 100644 --- a/tests/Settings/TestExtruderStack.py +++ b/tests/Settings/TestExtruderStack.py @@ -1,9 +1,8 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import pytest #This module contains automated tests. import unittest.mock #For the mocking and monkeypatching functionality. -import copy import cura.CuraApplication import UM.Settings.ContainerRegistry #To create empty instance containers. @@ -14,29 +13,27 @@ import cura.Settings.ExtruderStack #The module we're testing. from cura.Settings.Exceptions import InvalidContainerError, InvalidOperationError #To check whether the correct exceptions are raised. from cura.Settings.ExtruderManager import ExtruderManager -from UM.Settings.ContainerRegistry import ContainerRegistry from cura.Settings.GlobalStack import GlobalStack ## Fake container registry that always provides all containers you ask of. -@pytest.yield_fixture() -def container_registry(): - registry = unittest.mock.MagicMock() - registry.return_value = unittest.mock.NonCallableMagicMock() - registry.findInstanceContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - registry.findDefinitionContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = registry - UM.Settings.ContainerStack._containerRegistry = registry - - yield registry - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = None - UM.Settings.ContainerStack._containerRegistry = None +# @pytest.yield_fixture() +# def container_registry(): +# registry = unittest.mock.MagicMock() +# registry.return_value = unittest.mock.NonCallableMagicMock() +# registry.findInstanceContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] +# registry.findDefinitionContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] +# +# UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = registry +# UM.Settings.ContainerStack._containerRegistry = registry +# +# yield registry +# +# UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = None +# UM.Settings.ContainerStack._containerRegistry = None ## An empty extruder stack to test with. @pytest.fixture() def extruder_stack() -> cura.Settings.ExtruderStack.ExtruderStack: - creteEmptyContainers() return cura.Settings.ExtruderStack.ExtruderStack("TestStack") ## Gets an instance container with a specified container type. @@ -48,31 +45,6 @@ def getInstanceContainer(container_type) -> InstanceContainer: container.setMetaDataEntry("type", container_type) return container -def creteEmptyContainers(): - empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - ContainerRegistry.getInstance().addContainer(empty_variant_container) - - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - ContainerRegistry.getInstance().addContainer(empty_material_container) - - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - ContainerRegistry.getInstance().addContainer(empty_quality_container) - - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) - class DefinitionContainerSubClass(DefinitionContainer): def __init__(self): super().__init__(container_id = "SubDefinitionContainer") diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 3e74e3e575..1b583a9c98 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. import pytest #This module contains unit tests. diff --git a/tests/Settings/conftest.py b/tests/Settings/conftest.py new file mode 100644 index 0000000000..1ca3a865e9 --- /dev/null +++ b/tests/Settings/conftest.py @@ -0,0 +1,19 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Uranium is released under the terms of the LGPLv3 or higher. + +# The purpose of this class is to create fixtures or methods that can be shared among all settings tests. + +import pytest +import copy + +from UM.Settings.DefinitionContainer import DefinitionContainer #To provide definition containers in the registry fixtures. + +# Returns the CuraContainerRegistry instance with some empty containers. +@pytest.fixture() +def container_registry(application): + return application.getContainerRegistry() + +# Gives an arbitrary definition container. +@pytest.fixture() +def definition_container(): + return DefinitionContainer(container_id = "Test Definition") \ No newline at end of file diff --git a/tests/TestArrange.py b/tests/TestArrange.py index f383fc0cf3..7de3ec1d8d 100755 --- a/tests/TestArrange.py +++ b/tests/TestArrange.py @@ -1,9 +1,11 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + import numpy from cura.Arranging.Arrange import Arrange from cura.Arranging.ShapeArray import ShapeArray - ## Triangle of area 12 def gimmeTriangle(): return numpy.array([[-3, 1], [3, 1], [0, -3]], dtype=numpy.int32) @@ -102,7 +104,7 @@ def test_centerFirst_rectangular(): ## Test centerFirst -def test_centerFirst_rectangular(): +def test_centerFirst_rectangular2(): ar = Arrange(10, 20, 5, 10, scale = 1) ar.centerFirst() print(ar._priority) diff --git a/tests/TestMachineAction.py b/tests/TestMachineAction.py index 0118874a0b..7121fcc218 100755 --- a/tests/TestMachineAction.py +++ b/tests/TestMachineAction.py @@ -1,11 +1,10 @@ -#Todo: Write tests +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. import pytest -# QtApplication needs to be imported first to prevent import errors. -from UM.Qt.QtApplication import QtApplication from cura.MachineAction import MachineAction -from cura.MachineActionManager import MachineActionManager, NotUniqueMachineActionError, UnknownMachineActionError +from cura.MachineActionManager import NotUniqueMachineActionError, UnknownMachineActionError class Machine: def __init__(self, key = ""): @@ -14,66 +13,64 @@ class Machine: def getKey(self): return self._key -def test_addMachineAction(): - - machine_manager = MachineActionManager() +def test_addMachineAction(machine_action_manager): test_action = MachineAction(key = "test_action") test_action_2 = MachineAction(key = "test_action_2") test_machine = Machine("test_machine") - machine_manager.addMachineAction(test_action) - machine_manager.addMachineAction(test_action_2) + machine_action_manager.addMachineAction(test_action) + machine_action_manager.addMachineAction(test_action_2) - assert machine_manager.getMachineAction("test_action") == test_action - assert machine_manager.getMachineAction("key_that_doesnt_exist") is None + assert machine_action_manager.getMachineAction("test_action") == test_action + assert machine_action_manager.getMachineAction("key_that_doesnt_exist") is None # Adding the same machine action is not allowed. with pytest.raises(NotUniqueMachineActionError): - machine_manager.addMachineAction(test_action) + machine_action_manager.addMachineAction(test_action) # Check that the machine has no supported actions yet. - assert machine_manager.getSupportedActions(test_machine) == list() + assert machine_action_manager.getSupportedActions(test_machine) == list() # Check if adding a supported action works. - machine_manager.addSupportedAction(test_machine, "test_action") - assert machine_manager.getSupportedActions(test_machine) == [test_action, ] + machine_action_manager.addSupportedAction(test_machine, "test_action") + assert machine_action_manager.getSupportedActions(test_machine) == [test_action, ] # Check that adding a unknown action doesn't change anything. - machine_manager.addSupportedAction(test_machine, "key_that_doesnt_exist") - assert machine_manager.getSupportedActions(test_machine) == [test_action, ] + machine_action_manager.addSupportedAction(test_machine, "key_that_doesnt_exist") + assert machine_action_manager.getSupportedActions(test_machine) == [test_action, ] # Check if adding multiple supported actions works. - machine_manager.addSupportedAction(test_machine, "test_action_2") - assert machine_manager.getSupportedActions(test_machine) == [test_action, test_action_2] + machine_action_manager.addSupportedAction(test_machine, "test_action_2") + assert machine_action_manager.getSupportedActions(test_machine) == [test_action, test_action_2] # Check that the machine has no required actions yet. - assert machine_manager.getRequiredActions(test_machine) == set() + assert machine_action_manager.getRequiredActions(test_machine) == set() ## Ensure that only known actions can be added. with pytest.raises(UnknownMachineActionError): - machine_manager.addRequiredAction(test_machine, "key_that_doesnt_exist") + machine_action_manager.addRequiredAction(test_machine, "key_that_doesnt_exist") ## Check if adding single required action works - machine_manager.addRequiredAction(test_machine, "test_action") - assert machine_manager.getRequiredActions(test_machine) == [test_action, ] + machine_action_manager.addRequiredAction(test_machine, "test_action") + assert machine_action_manager.getRequiredActions(test_machine) == [test_action, ] # Check if adding multiple required actions works. - machine_manager.addRequiredAction(test_machine, "test_action_2") - assert machine_manager.getRequiredActions(test_machine) == [test_action, test_action_2] + machine_action_manager.addRequiredAction(test_machine, "test_action_2") + assert machine_action_manager.getRequiredActions(test_machine) == [test_action, test_action_2] # Ensure that firstStart actions are empty by default. - assert machine_manager.getFirstStartActions(test_machine) == [] + assert machine_action_manager.getFirstStartActions(test_machine) == [] # Check if adding multiple (the same) actions to first start actions work. - machine_manager.addFirstStartAction(test_machine, "test_action") - machine_manager.addFirstStartAction(test_machine, "test_action") - assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action] + machine_action_manager.addFirstStartAction(test_machine, "test_action") + machine_action_manager.addFirstStartAction(test_machine, "test_action") + assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action] # Check if inserting an action works - machine_manager.addFirstStartAction(test_machine, "test_action_2", index = 1) - assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] + machine_action_manager.addFirstStartAction(test_machine, "test_action_2", index = 1) + assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] # Check that adding a unknown action doesn't change anything. - machine_manager.addFirstStartAction(test_machine, "key_that_doesnt_exist", index = 1) - assert machine_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] + machine_action_manager.addFirstStartAction(test_machine, "key_that_doesnt_exist", index = 1) + assert machine_action_manager.getFirstStartActions(test_machine) == [test_action, test_action_2, test_action] diff --git a/tests/TestProfileRequirements.py b/tests/TestProfileRequirements.py index f75ca9da8d..97641fe753 100644 --- a/tests/TestProfileRequirements.py +++ b/tests/TestProfileRequirements.py @@ -1,3 +1,6 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + import configparser #To read the profiles. import os #To join paths. import pytest @@ -11,6 +14,7 @@ import pytest # often that we updated the variants for the UM3 but forgot about the UM3E. @pytest.mark.parametrize("um3_file, um3e_file", [ #List the corresponding files below. + ("ultimaker3_aa0.25.inst.cfg", "ultimaker3_extended_aa0.25.inst.cfg"), ("ultimaker3_aa0.8.inst.cfg", "ultimaker3_extended_aa0.8.inst.cfg"), ("ultimaker3_aa04.inst.cfg", "ultimaker3_extended_aa04.inst.cfg"), ("ultimaker3_bb0.8.inst.cfg", "ultimaker3_extended_bb0.8.inst.cfg"), diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000000..32e2dc621f --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,38 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +# The purpose of this class is to create fixtures or methods that can be shared among all tests. + +import pytest +from UM.Qt.QtApplication import QtApplication #QTApplication import is required, even though it isn't used. +from cura.CuraApplication import CuraApplication +from cura.MachineActionManager import MachineActionManager + +# Create a CuraApplication object that will be shared among all tests. It needs to be initialized. +# Since we need to use it more that once, we create the application the first time and use its instance afterwards. +@pytest.fixture() +def application() -> CuraApplication: + application = CuraApplication.getInstance() + if application is None: + application = CuraApplication() + application.initialize() + return application + +# Returns a MachineActionManager instance. +@pytest.fixture() +def machine_action_manager(application) -> MachineActionManager: + return application.getMachineActionManager() + +# @pytest.fixture() +# def plugin_registry(application): +# PluginRegistry._PluginRegistry__instance = None +# plugin_registry = PluginRegistry(application) +# plugin_registry._plugin_locations = [] # Clear pre-defined plugin locations +# return plugin_registry +# +# @pytest.fixture() +# def upgrade_manager(application): +# VersionUpgradeManager._VersionUpgradeManager__instance = None +# upgrade_manager = VersionUpgradeManager(application) +# return upgrade_manager + From c8af4f45cedf1e3ae8e56df1fdbf4169a0fe6430 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 14 Aug 2018 13:25:56 +0200 Subject: [PATCH 04/29] Decouple the creation of the stack containers from the process that add them to the container registry, that is done in CuraApplication. That allow us to have access to the empty containers and so we can unit test easily without mocking up stuff. Contributes to CURA-5628. --- cura/CuraApplication.py | 46 ++++++++--------------------- cura/CuraEmptyInstanceContainers.py | 29 ++++++++++++++++++ cura/Settings/CuraContainerStack.py | 16 +++++----- 3 files changed, 49 insertions(+), 42 deletions(-) create mode 100644 cura/CuraEmptyInstanceContainers.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 78986d82ee..24043b83fe 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1,11 +1,10 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import copy import os import sys import time -from typing import cast, TYPE_CHECKING, Optional +from typing import cast, TYPE_CHECKING import numpy @@ -105,6 +104,7 @@ from cura.Settings.ExtrudersModel import ExtrudersModel from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler from cura.Settings.ContainerManager import ContainerManager from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel +import cura.CuraEmptyInstanceContainers from cura.ObjectsModel import ObjectsModel @@ -368,42 +368,20 @@ class CuraApplication(QtApplication): # Add empty variant, material and quality containers. # Since they are empty, they should never be serialized and instead just programmatically created. # We need them to simplify the switching between materials. - empty_container = self._container_registry.getEmptyInstanceContainer() - self.empty_container = empty_container + self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_definition_changes_container) + self.empty_definition_changes_container = cura.CuraEmptyInstanceContainers.empty_definition_changes_container - empty_definition_changes_container = copy.deepcopy(empty_container) - empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes") - empty_definition_changes_container.setMetaDataEntry("type", "definition_changes") - self._container_registry.addContainer(empty_definition_changes_container) - self.empty_definition_changes_container = empty_definition_changes_container + self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_variant_container) + self.empty_variant_container = cura.CuraEmptyInstanceContainers.empty_variant_container - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - self._container_registry.addContainer(empty_variant_container) - self.empty_variant_container = empty_variant_container + self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_material_container) + self.empty_material_container = cura.CuraEmptyInstanceContainers.empty_material_container - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - self._container_registry.addContainer(empty_material_container) - self.empty_material_container = empty_material_container + self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_quality_container) + self.empty_quality_container = cura.CuraEmptyInstanceContainers.empty_quality_container - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - self._container_registry.addContainer(empty_quality_container) - self.empty_quality_container = empty_quality_container - - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported") - self._container_registry.addContainer(empty_quality_changes_container) - self.empty_quality_changes_container = empty_quality_changes_container + self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_quality_changes_container) + self.empty_quality_changes_container = cura.CuraEmptyInstanceContainers.empty_quality_changes_container # Initializes the version upgrade manager with by providing the paths for each resource type and the latest # versions. diff --git a/cura/CuraEmptyInstanceContainers.py b/cura/CuraEmptyInstanceContainers.py new file mode 100644 index 0000000000..3f5d3e7c59 --- /dev/null +++ b/cura/CuraEmptyInstanceContainers.py @@ -0,0 +1,29 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Settings.EmptyInstanceContainer import empty_container +import copy + +empty_definition_changes_container = copy.deepcopy(empty_container) +empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes") +empty_definition_changes_container.setMetaDataEntry("type", "definition_changes") + +empty_variant_container = copy.deepcopy(empty_container) +empty_variant_container.setMetaDataEntry("id", "empty_variant") +empty_variant_container.setMetaDataEntry("type", "variant") + +empty_material_container = copy.deepcopy(empty_container) +empty_material_container.setMetaDataEntry("id", "empty_material") +empty_material_container.setMetaDataEntry("type", "material") + +empty_quality_container = copy.deepcopy(empty_container) +empty_quality_container.setMetaDataEntry("id", "empty_quality") +empty_quality_container.setName("Not Supported") +empty_quality_container.setMetaDataEntry("quality_type", "not_supported") +empty_quality_container.setMetaDataEntry("type", "quality") +empty_quality_container.setMetaDataEntry("supported", False) + +empty_quality_changes_container = copy.deepcopy(empty_container) +empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") +empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") +empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported") diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index bd3380dfb2..dabed97011 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Any, cast, List, Optional, Union +from typing import Any, cast, List, Optional from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject from UM.Application import Application @@ -13,6 +13,8 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.DefinitionContainer import DefinitionContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Interfaces import ContainerInterface, DefinitionContainerInterface +from UM.Settings.EmptyInstanceContainer import empty_container +from cura import CuraEmptyInstanceContainers from . import Exceptions @@ -39,14 +41,12 @@ class CuraContainerStack(ContainerStack): def __init__(self, container_id: str) -> None: super().__init__(container_id) - self._container_registry = ContainerRegistry.getInstance() #type: ContainerRegistry + self._empty_instance_container = empty_container #type: InstanceContainer - self._empty_instance_container = self._container_registry.getEmptyInstanceContainer() #type: InstanceContainer - - self._empty_quality_changes = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0] #type: InstanceContainer - self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0] #type: InstanceContainer - self._empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0] #type: InstanceContainer - self._empty_variant = self._container_registry.findInstanceContainers(id = "empty_variant")[0] #type: InstanceContainer + self._empty_quality_changes = CuraEmptyInstanceContainers.empty_quality_changes_container #type: InstanceContainer + self._empty_quality = CuraEmptyInstanceContainers.empty_quality_container #type: InstanceContainer + self._empty_material = CuraEmptyInstanceContainers.empty_material_container #type: InstanceContainer + self._empty_variant = CuraEmptyInstanceContainers.empty_variant_container #type: InstanceContainer self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))] #type: List[ContainerInterface] self._containers[_ContainerIndexes.QualityChanges] = self._empty_quality_changes From 1364370ede4ecbe71c077b56371a55971639a9fa Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 14 Aug 2018 13:49:37 +0200 Subject: [PATCH 05/29] Fix global stack tests. Contributes to CURA-5628. --- tests/Settings/TestGlobalStack.py | 117 +++++++----------------------- tests/Settings/conftest.py | 27 ++++++- tests/conftest.py | 17 +---- 3 files changed, 50 insertions(+), 111 deletions(-) diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 1b583a9c98..9d52257245 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -3,41 +3,16 @@ import pytest #This module contains unit tests. import unittest.mock #To monkeypatch some mocks in place of dependencies. -import copy -import cura.CuraApplication -import cura.Settings.GlobalStack #The module we're testing. import cura.Settings.CuraContainerStack #To get the list of container types. -from cura.Settings.Exceptions import TooManyExtrudersError, InvalidContainerError, InvalidOperationError #To test raising these errors. +from cura.Settings.Exceptions import InvalidContainerError, InvalidOperationError #To test raising these errors. from UM.Settings.DefinitionContainer import DefinitionContainer #To test against the class DefinitionContainer. from UM.Settings.InstanceContainer import InstanceContainer #To test against the class InstanceContainer. from UM.Settings.SettingInstance import InstanceState +from UM.Settings.EmptyInstanceContainer import empty_container import UM.Settings.ContainerRegistry import UM.Settings.ContainerStack import UM.Settings.SettingDefinition #To add settings to the definition. -from UM.Settings.ContainerRegistry import ContainerRegistry - -## Fake container registry that always provides all containers you ask of. -@pytest.yield_fixture() -def container_registry(): - registry = unittest.mock.MagicMock() - registry.return_value = unittest.mock.NonCallableMagicMock() - registry.findInstanceContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - registry.findDefinitionContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = registry - UM.Settings.ContainerStack._containerRegistry = registry - - yield registry - - UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = None - UM.Settings.ContainerStack._containerRegistry = None - -#An empty global stack to test with. -@pytest.fixture() -def global_stack() -> cura.Settings.GlobalStack.GlobalStack: - creteEmptyContainers() - return cura.Settings.GlobalStack.GlobalStack("TestStack") ## Gets an instance container with a specified container type. # @@ -48,31 +23,6 @@ def getInstanceContainer(container_type) -> InstanceContainer: container.setMetaDataEntry("type", container_type) return container -def creteEmptyContainers(): - empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer() - empty_variant_container = copy.deepcopy(empty_container) - empty_variant_container.setMetaDataEntry("id", "empty_variant") - empty_variant_container.setMetaDataEntry("type", "variant") - ContainerRegistry.getInstance().addContainer(empty_variant_container) - - empty_material_container = copy.deepcopy(empty_container) - empty_material_container.setMetaDataEntry("id", "empty_material") - empty_material_container.setMetaDataEntry("type", "material") - ContainerRegistry.getInstance().addContainer(empty_material_container) - - empty_quality_container = copy.deepcopy(empty_container) - empty_quality_container.setMetaDataEntry("id", "empty_quality") - empty_quality_container.setName("Not Supported") - empty_quality_container.setMetaDataEntry("quality_type", "not_supported") - empty_quality_container.setMetaDataEntry("type", "quality") - empty_quality_container.setMetaDataEntry("supported", False) - ContainerRegistry.getInstance().addContainer(empty_quality_container) - - empty_quality_changes_container = copy.deepcopy(empty_container) - empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") - empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") - ContainerRegistry.getInstance().addContainer(empty_quality_changes_container) - class DefinitionContainerSubClass(DefinitionContainer): def __init__(self): super().__init__(container_id = "SubDefinitionContainer") @@ -241,23 +191,22 @@ def test_constrainVariantInvalid(container, global_stack): def test_constrainDefinitionValid(container, global_stack): global_stack.definition = container #Should not give an error. -## Tests whether deserialising completes the missing containers with empty -# ones. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. -def test_deserializeCompletesEmptyContainers(global_stack: cura.Settings.GlobalStack): - global_stack._containers = [DefinitionContainer(container_id = "definition")] #Set the internal state of this stack manually. +## Tests whether deserialising completes the missing containers with empty ones. The initial containers are just the +# definition and the definition_changes (that cannot be empty after CURA-5281) +def test_deserializeCompletesEmptyContainers(global_stack): + global_stack._containers = [DefinitionContainer(container_id = "definition"), global_stack.definitionChanges] #Set the internal state of this stack manually. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. global_stack.deserialize("") assert len(global_stack.getContainers()) == len(cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap) #Needs a slot for every type. for container_type_index in cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap: - if container_type_index == cura.Settings.CuraContainerStack._ContainerIndexes.Definition: #We're not checking the definition. + if container_type_index in \ + (cura.Settings.CuraContainerStack._ContainerIndexes.Definition, cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges): #We're not checking the definition or definition_changes continue - assert global_stack.getContainer(container_type_index).getId() == "empty" #All others need to be empty. + assert global_stack.getContainer(container_type_index) == empty_container #All others need to be empty. -## Tests whether an instance container with the wrong type gets removed when -# deserialising. +## Tests whether an instance container with the wrong type gets removed when deserialising. def test_deserializeRemovesWrongInstanceContainer(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "wrong type") global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -267,8 +216,7 @@ def test_deserializeRemovesWrongInstanceContainer(global_stack): assert global_stack.quality == global_stack._empty_instance_container #Replaced with empty. -## Tests whether a container with the wrong class gets removed when -# deserialising. +## Tests whether a container with the wrong class gets removed when deserialising. def test_deserializeRemovesWrongContainerClass(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = DefinitionContainer(container_id = "wrong class") global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -278,8 +226,7 @@ def test_deserializeRemovesWrongContainerClass(global_stack): assert global_stack.quality == global_stack._empty_instance_container #Replaced with empty. -## Tests whether an instance container in the definition spot results in an -# error. +## Tests whether an instance container in the definition spot results in an error. def test_deserializeWrongDefinitionClass(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = getInstanceContainer(container_type = "definition") #Correct type but wrong class. @@ -287,8 +234,7 @@ def test_deserializeWrongDefinitionClass(global_stack): with pytest.raises(UM.Settings.ContainerStack.InvalidContainerStackError): #Must raise an error that there is no definition container. global_stack.deserialize("") -## Tests whether an instance container with the wrong type is moved into the -# correct slot by deserialising. +## Tests whether an instance container with the wrong type is moved into the correct slot by deserialising. def test_deserializeMoveInstanceContainer(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "material") #Not in the correct spot. global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -296,25 +242,20 @@ def test_deserializeMoveInstanceContainer(global_stack): with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. global_stack.deserialize("") - assert global_stack.quality.getId() == "empty" - assert global_stack.material.getId() != "empty" + assert global_stack.quality == empty_container + assert global_stack.material != empty_container -## Tests whether a definition container in the wrong spot is moved into the -# correct spot by deserialising. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. +## Tests whether a definition container in the wrong spot is moved into the correct spot by deserialising. def test_deserializeMoveDefinitionContainer(global_stack): global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Material] = DefinitionContainer(container_id = "some definition") #Not in the correct spot. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. global_stack.deserialize("") - assert global_stack.material.getId() == "empty" - assert global_stack.definition.getId() != "empty" + assert global_stack.material == empty_container + assert global_stack.definition != empty_container - UM.Settings.ContainerStack._containerRegistry = None - -## Tests whether getProperty properly applies the stack-like behaviour on its -# containers. +## Tests whether getProperty properly applies the stack-like behaviour on its containers. def test_getPropertyFallThrough(global_stack): #A few instance container mocks to put in the stack. mock_layer_heights = {} #For each container type, a mock container that defines layer height to something unique. @@ -365,8 +306,7 @@ def test_getPropertyNoResolveInDefinition(global_stack): global_stack.definition = value assert global_stack.getProperty("material_bed_temperature", "value") == 10 #No resolve, so fall through to value. -## In definitions, when the value is asked and there is a resolve function, it -# must get the resolve first. +## In definitions, when the value is asked and there is a resolve function, it must get the resolve first. def test_getPropertyResolveInDefinition(global_stack): resolve_and_value = unittest.mock.MagicMock() #Sets the resolve and value for bed temperature. resolve_and_value.getProperty = lambda key, property, context = None: (7.5 if property == "resolve" else 5) if (key == "material_bed_temperature" and property in ("resolve", "value")) else None #7.5 resolve, 5 value. @@ -375,8 +315,7 @@ def test_getPropertyResolveInDefinition(global_stack): global_stack.definition = resolve_and_value assert global_stack.getProperty("material_bed_temperature", "value") == 7.5 #Resolve wins in the definition. -## In instance containers, when the value is asked and there is a resolve -# function, it must get the value first. +## In instance containers, when the value is asked and there is a resolve function, it must get the value first. def test_getPropertyResolveInInstance(global_stack): container_indices = cura.Settings.CuraContainerStack._ContainerIndexes instance_containers = {} @@ -402,8 +341,7 @@ def test_getPropertyResolveInInstance(global_stack): global_stack.userChanges = instance_containers[container_indices.UserChanges] assert global_stack.getProperty("material_bed_temperature", "value") == 5 -## Tests whether the value in instances gets evaluated before the resolve in -# definitions. +## Tests whether the value in instances gets evaluated before the resolve in definitions. def test_getPropertyInstancesBeforeResolve(global_stack): value = unittest.mock.MagicMock() #Sets just the value. value.getProperty = lambda key, property, context = None: (10 if property == "value" else (InstanceState.User if property != "limit_to_extruder" else "-1")) if key == "material_bed_temperature" else None @@ -417,8 +355,7 @@ def test_getPropertyInstancesBeforeResolve(global_stack): assert global_stack.getProperty("material_bed_temperature", "value") == 10 -## Tests whether the hasUserValue returns true for settings that are changed in -# the user-changes container. +## Tests whether the hasUserValue returns true for settings that are changed in the user-changes container. def test_hasUserValueUserChanges(global_stack): container = unittest.mock.MagicMock() container.getMetaDataEntry = unittest.mock.MagicMock(return_value = "user") @@ -429,8 +366,7 @@ def test_hasUserValueUserChanges(global_stack): assert not global_stack.hasUserValue("infill_sparse_density") assert not global_stack.hasUserValue("") -## Tests whether the hasUserValue returns true for settings that are changed in -# the quality-changes container. +## Tests whether the hasUserValue returns true for settings that are changed in the quality-changes container. def test_hasUserValueQualityChanges(global_stack): container = unittest.mock.MagicMock() container.getMetaDataEntry = unittest.mock.MagicMock(return_value = "quality_changes") @@ -441,8 +377,7 @@ def test_hasUserValueQualityChanges(global_stack): assert not global_stack.hasUserValue("infill_sparse_density") assert not global_stack.hasUserValue("") -## Tests whether a container in some other place on the stack is correctly not -# recognised as user value. +## Tests whether a container in some other place on the stack is correctly not recognised as user value. def test_hasNoUserValue(global_stack): container = unittest.mock.MagicMock() container.getMetaDataEntry = unittest.mock.MagicMock(return_value = "quality") @@ -481,4 +416,4 @@ def test_setPropertyUser(key, property, value, global_stack): global_stack.setProperty(key, property, value) #The actual test. - global_stack.userChanges.setProperty.assert_called_once_with(key, property, value) #Make sure that the user container gets a setProperty call. \ No newline at end of file + global_stack.userChanges.setProperty.assert_called_once_with(key, property, value, None, False) #Make sure that the user container gets a setProperty call. \ No newline at end of file diff --git a/tests/Settings/conftest.py b/tests/Settings/conftest.py index 1ca3a865e9..f7affc94b2 100644 --- a/tests/Settings/conftest.py +++ b/tests/Settings/conftest.py @@ -4,16 +4,35 @@ # The purpose of this class is to create fixtures or methods that can be shared among all settings tests. import pytest -import copy from UM.Settings.DefinitionContainer import DefinitionContainer #To provide definition containers in the registry fixtures. +from UM.Settings.InstanceContainer import InstanceContainer +from cura.Settings.CuraContainerRegistry import CuraContainerRegistry +from cura.Settings.ExtruderStack import ExtruderStack +from cura.Settings.GlobalStack import GlobalStack +import cura.Settings.CuraContainerStack # Returns the CuraContainerRegistry instance with some empty containers. @pytest.fixture() -def container_registry(application): +def container_registry(application) -> CuraContainerRegistry: return application.getContainerRegistry() # Gives an arbitrary definition container. @pytest.fixture() -def definition_container(): - return DefinitionContainer(container_id = "Test Definition") \ No newline at end of file +def definition_container() -> DefinitionContainer: + return DefinitionContainer(container_id = "Test Definition") + +#An empty global stack to test with. +@pytest.fixture() +def global_stack() -> GlobalStack: + global_stack = GlobalStack("TestGlobalStack") + # There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 + definition_changes_container = InstanceContainer(container_id = "InstanceContainer") + definition_changes_container.setMetaDataEntry("type", "definition_changes") + global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container + return global_stack + +## An empty extruder stack to test with. +@pytest.fixture() +def extruder_stack() -> ExtruderStack: + return ExtruderStack("TestExtruderStack") \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 32e2dc621f..d5bb5c8109 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,7 +4,7 @@ # The purpose of this class is to create fixtures or methods that can be shared among all tests. import pytest -from UM.Qt.QtApplication import QtApplication #QTApplication import is required, even though it isn't used. +from UM.Qt.QtApplication import QtApplication #QtApplication import is required, even though it isn't used. from cura.CuraApplication import CuraApplication from cura.MachineActionManager import MachineActionManager @@ -15,24 +15,9 @@ def application() -> CuraApplication: application = CuraApplication.getInstance() if application is None: application = CuraApplication() - application.initialize() return application # Returns a MachineActionManager instance. @pytest.fixture() def machine_action_manager(application) -> MachineActionManager: return application.getMachineActionManager() - -# @pytest.fixture() -# def plugin_registry(application): -# PluginRegistry._PluginRegistry__instance = None -# plugin_registry = PluginRegistry(application) -# plugin_registry._plugin_locations = [] # Clear pre-defined plugin locations -# return plugin_registry -# -# @pytest.fixture() -# def upgrade_manager(application): -# VersionUpgradeManager._VersionUpgradeManager__instance = None -# upgrade_manager = VersionUpgradeManager(application) -# return upgrade_manager - From ce9782b3af2e2ffbdfe79d97e92c703259c98edc Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 14 Aug 2018 15:32:04 +0200 Subject: [PATCH 06/29] Initialize the empty_container in CuraApplication. Contributes to CURA-5628. --- cura/CuraApplication.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 24043b83fe..d688052369 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -368,6 +368,8 @@ class CuraApplication(QtApplication): # Add empty variant, material and quality containers. # Since they are empty, they should never be serialized and instead just programmatically created. # We need them to simplify the switching between materials. + self.empty_container = cura.CuraEmptyInstanceContainers.empty_container + self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_definition_changes_container) self.empty_definition_changes_container = cura.CuraEmptyInstanceContainers.empty_definition_changes_container From e1fd9b03a4a90e5cfa5b19c39f295975cc6ba7a2 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 14 Aug 2018 15:33:35 +0200 Subject: [PATCH 07/29] Remove all dependencies of the CuraContainerStack with the ContainerRegistry. That will be very helpful for creating unit tests. Also this is not needed because the next stack is always set in the machine or extruder manager when switching printers. Contributes to CURA-5628. --- cura/Settings/ExtruderStack.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 47846fc1dd..ca687e358b 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -139,9 +139,6 @@ class ExtruderStack(CuraContainerStack): super().deserialize(contents, file_name) if "enabled" not in self.getMetaData(): self.setMetaDataEntry("enabled", "True") - stacks = ContainerRegistry.getInstance().findContainerStacks(id=self.getMetaDataEntry("machine", "")) - if stacks: - self.setNextStack(stacks[0]) def _onPropertiesChanged(self, key: str, properties: Dict[str, Any]) -> None: # When there is a setting that is not settable per extruder that depends on a value from a setting that is, From b85950b1281c7d1498d0a51fd09a6a600bca0f84 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 14 Aug 2018 15:40:11 +0200 Subject: [PATCH 08/29] Fix tests in the ExtruderStack. Contributes to CURA-5628. --- tests/Settings/TestExtruderStack.py | 99 ++++++++++++----------------- tests/Settings/TestGlobalStack.py | 2 +- tests/Settings/conftest.py | 7 +- 3 files changed, 49 insertions(+), 59 deletions(-) diff --git a/tests/Settings/TestExtruderStack.py b/tests/Settings/TestExtruderStack.py index a19f99571d..b2fa171068 100644 --- a/tests/Settings/TestExtruderStack.py +++ b/tests/Settings/TestExtruderStack.py @@ -4,37 +4,14 @@ import pytest #This module contains automated tests. import unittest.mock #For the mocking and monkeypatching functionality. -import cura.CuraApplication +import cura.Settings.CuraContainerStack #To get the list of container types. import UM.Settings.ContainerRegistry #To create empty instance containers. import UM.Settings.ContainerStack #To set the container registry the container stacks use. from UM.Settings.DefinitionContainer import DefinitionContainer #To check against the class of DefinitionContainer. from UM.Settings.InstanceContainer import InstanceContainer #To check against the class of InstanceContainer. -import cura.Settings.ExtruderStack #The module we're testing. +from UM.Settings.EmptyInstanceContainer import empty_container from cura.Settings.Exceptions import InvalidContainerError, InvalidOperationError #To check whether the correct exceptions are raised. - from cura.Settings.ExtruderManager import ExtruderManager -from cura.Settings.GlobalStack import GlobalStack - -## Fake container registry that always provides all containers you ask of. -# @pytest.yield_fixture() -# def container_registry(): -# registry = unittest.mock.MagicMock() -# registry.return_value = unittest.mock.NonCallableMagicMock() -# registry.findInstanceContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] -# registry.findDefinitionContainers = lambda *args, registry = registry, **kwargs: [registry.return_value] -# -# UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = registry -# UM.Settings.ContainerStack._containerRegistry = registry -# -# yield registry -# -# UM.Settings.ContainerRegistry.ContainerRegistry._ContainerRegistry__instance = None -# UM.Settings.ContainerStack._containerRegistry = None - -## An empty extruder stack to test with. -@pytest.fixture() -def extruder_stack() -> cura.Settings.ExtruderStack.ExtruderStack: - return cura.Settings.ExtruderStack.ExtruderStack("TestStack") ## Gets an instance container with a specified container type. # @@ -151,12 +128,30 @@ def test_constrainVariantInvalid(container, extruder_stack): def test_constrainVariantValid(container, extruder_stack): extruder_stack.variant = container #Should not give an error. +#Tests setting definition changes profiles to invalid containers. +@pytest.mark.parametrize("container", [ + getInstanceContainer(container_type = "wrong container type"), + getInstanceContainer(container_type = "material"), #Existing, but still wrong type. + DefinitionContainer(container_id = "wrong class") +]) +def test_constrainDefinitionChangesInvalid(container, global_stack): + with pytest.raises(InvalidContainerError): #Invalid container, should raise an error. + global_stack.definitionChanges = container + +#Test setting definition changes profiles. +@pytest.mark.parametrize("container", [ + getInstanceContainer(container_type = "definition_changes"), + InstanceContainerSubClass(container_type = "definition_changes") +]) +def test_constrainDefinitionChangesValid(container, global_stack): + global_stack.definitionChanges = container #Should not give an error. + #Tests setting definitions to invalid containers. @pytest.mark.parametrize("container", [ getInstanceContainer(container_type = "wrong class"), getInstanceContainer(container_type = "material"), #Existing, but still wrong class. ]) -def test_constrainVariantInvalid(container, extruder_stack): +def test_constrainDefinitionInvalid(container, extruder_stack): with pytest.raises(InvalidContainerError): #Invalid container, should raise an error. extruder_stack.definition = container @@ -168,23 +163,22 @@ def test_constrainVariantInvalid(container, extruder_stack): def test_constrainDefinitionValid(container, extruder_stack): extruder_stack.definition = container #Should not give an error. -## Tests whether deserialising completes the missing containers with empty -# ones. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. -def test_deserializeCompletesEmptyContainers(extruder_stack: cura.Settings.ExtruderStack): - extruder_stack._containers = [DefinitionContainer(container_id = "definition")] #Set the internal state of this stack manually. +## Tests whether deserialising completes the missing containers with empty ones. +def test_deserializeCompletesEmptyContainers(extruder_stack): + extruder_stack._containers = [DefinitionContainer(container_id = "definition"), extruder_stack.definitionChanges] #Set the internal state of this stack manually. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. extruder_stack.deserialize("") assert len(extruder_stack.getContainers()) == len(cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap) #Needs a slot for every type. for container_type_index in cura.Settings.CuraContainerStack._ContainerIndexes.IndexTypeMap: - if container_type_index == cura.Settings.CuraContainerStack._ContainerIndexes.Definition: #We're not checking the definition. + if container_type_index in \ + (cura.Settings.CuraContainerStack._ContainerIndexes.Definition, + cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges): # We're not checking the definition or definition_changes continue - assert extruder_stack.getContainer(container_type_index).getId() == "empty" #All others need to be empty. + assert extruder_stack.getContainer(container_type_index) == empty_container #All others need to be empty. -## Tests whether an instance container with the wrong type gets removed when -# deserialising. +## Tests whether an instance container with the wrong type gets removed when deserialising. def test_deserializeRemovesWrongInstanceContainer(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "wrong type") extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -194,8 +188,7 @@ def test_deserializeRemovesWrongInstanceContainer(extruder_stack): assert extruder_stack.quality == extruder_stack._empty_instance_container #Replaced with empty. -## Tests whether a container with the wrong class gets removed when -# deserialising. +## Tests whether a container with the wrong class gets removed when deserialising. def test_deserializeRemovesWrongContainerClass(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = DefinitionContainer(container_id = "wrong class") extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -205,8 +198,7 @@ def test_deserializeRemovesWrongContainerClass(extruder_stack): assert extruder_stack.quality == extruder_stack._empty_instance_container #Replaced with empty. -## Tests whether an instance container in the definition spot results in an -# error. +## Tests whether an instance container in the definition spot results in an error. def test_deserializeWrongDefinitionClass(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = getInstanceContainer(container_type = "definition") #Correct type but wrong class. @@ -214,8 +206,7 @@ def test_deserializeWrongDefinitionClass(extruder_stack): with pytest.raises(UM.Settings.ContainerStack.InvalidContainerStackError): #Must raise an error that there is no definition container. extruder_stack.deserialize("") -## Tests whether an instance container with the wrong type is moved into the -# correct slot by deserialising. +## Tests whether an instance container with the wrong type is moved into the correct slot by deserialising. def test_deserializeMoveInstanceContainer(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Quality] = getInstanceContainer(container_type = "material") #Not in the correct spot. extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Definition] = DefinitionContainer(container_id = "some definition") @@ -223,26 +214,21 @@ def test_deserializeMoveInstanceContainer(extruder_stack): with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. extruder_stack.deserialize("") - assert extruder_stack.quality.getId() == "empty" - assert extruder_stack.material.getId() != "empty" -from UM.Settings.Validator import Validator -## Tests whether a definition container in the wrong spot is moved into the -# correct spot by deserialising. -@pytest.mark.skip #The test currently fails because the definition container doesn't have a category, which is wrong but we don't have time to refactor that right now. + assert extruder_stack.quality == empty_container + assert extruder_stack.material != empty_container + +## Tests whether a definition container in the wrong spot is moved into the correct spot by deserialising. def test_deserializeMoveDefinitionContainer(extruder_stack): extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.Material] = DefinitionContainer(container_id = "some definition") #Not in the correct spot. with unittest.mock.patch("UM.Settings.ContainerStack.ContainerStack.deserialize", unittest.mock.MagicMock()): #Prevent calling super().deserialize. extruder_stack.deserialize("") - assert extruder_stack.material.getId() == "empty" - assert extruder_stack.definition.getId() != "empty" + assert extruder_stack.material == empty_container + assert extruder_stack.definition != empty_container - UM.Settings.ContainerStack._containerRegistry = None - -## Tests whether getProperty properly applies the stack-like behaviour on its -# containers. -def test_getPropertyFallThrough(extruder_stack): +## Tests whether getProperty properly applies the stack-like behaviour on its containers. +def test_getPropertyFallThrough(global_stack, extruder_stack): # ExtruderStack.setNextStack calls registerExtruder for backward compatibility, but we do not need a complete extruder manager ExtruderManager._ExtruderManager__instance = unittest.mock.MagicMock() @@ -272,8 +258,7 @@ def test_getPropertyFallThrough(extruder_stack): with unittest.mock.patch("cura.Settings.CuraContainerStack.DefinitionContainer", unittest.mock.MagicMock): #To guard against the type checking. extruder_stack.definition = mock_layer_heights[container_indices.Definition] #There's a layer height in here! - stack = GlobalStack("PyTest GlobalStack") - extruder_stack.setNextStack(stack) + extruder_stack.setNextStack(global_stack) assert extruder_stack.getProperty("layer_height", "value") == container_indices.Definition extruder_stack.variant = mock_layer_heights[container_indices.Variant] @@ -312,4 +297,4 @@ def test_setPropertyUser(key, property, value, extruder_stack): extruder_stack.setProperty(key, property, value) #The actual test. - extruder_stack.userChanges.setProperty.assert_called_once_with(key, property, value) #Make sure that the user container gets a setProperty call. \ No newline at end of file + extruder_stack.userChanges.setProperty.assert_called_once_with(key, property, value, None, False) #Make sure that the user container gets a setProperty call. \ No newline at end of file diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 9d52257245..7aba53c4e5 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -179,7 +179,7 @@ def test_constrainDefinitionChangesValid(container, global_stack): getInstanceContainer(container_type = "wrong class"), getInstanceContainer(container_type = "material"), #Existing, but still wrong class. ]) -def test_constrainVariantInvalid(container, global_stack): +def test_constrainDefinitionInvalid(container, global_stack): with pytest.raises(InvalidContainerError): #Invalid container, should raise an error. global_stack.definition = container diff --git a/tests/Settings/conftest.py b/tests/Settings/conftest.py index f7affc94b2..8b519fd261 100644 --- a/tests/Settings/conftest.py +++ b/tests/Settings/conftest.py @@ -35,4 +35,9 @@ def global_stack() -> GlobalStack: ## An empty extruder stack to test with. @pytest.fixture() def extruder_stack() -> ExtruderStack: - return ExtruderStack("TestExtruderStack") \ No newline at end of file + extruder_stack= ExtruderStack("TestExtruderStack") + # There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 + definition_changes_container = InstanceContainer(container_id = "InstanceContainer") + definition_changes_container.setMetaDataEntry("type", "definition_changes") + extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container + return extruder_stack \ No newline at end of file From 77c5a94db2cb1f6d5ce1b88c6feff66841042b9f Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 14 Aug 2018 17:14:30 +0200 Subject: [PATCH 09/29] Fix some test in the CuraContainerRegistry. Delete a test that needs a ContainerProvider. We need to discuss if we want to add it back, depending if we are still keeping the providers. Contributes to CURA-5628. --- tests/Settings/TestCuraContainerRegistry.py | 56 +++++-------------- tests/Settings/conftest.py | 33 +++++++---- tests/Settings/stacks/Complete.extruder.cfg | 12 ---- tests/Settings/stacks/Complete.global.cfg | 13 ----- .../Settings/stacks/ExtruderLegacy.stack.cfg | 11 ---- tests/Settings/stacks/Global.global.cfg | 8 --- tests/Settings/stacks/Global.stack.cfg | 11 ---- tests/Settings/stacks/Left.extruder.cfg | 8 --- tests/Settings/stacks/MachineLegacy.stack.cfg | 11 ---- .../stacks/OnlyDefinition.extruder.cfg | 7 --- .../Settings/stacks/OnlyDefinition.global.cfg | 7 --- .../stacks/OnlyDefinitionChanges.global.cfg | 8 --- .../Settings/stacks/OnlyMaterial.extruder.cfg | 8 --- tests/Settings/stacks/OnlyMaterial.global.cfg | 8 --- .../Settings/stacks/OnlyQuality.extruder.cfg | 8 --- tests/Settings/stacks/OnlyQuality.global.cfg | 8 --- .../stacks/OnlyQualityChanges.extruder.cfg | 8 --- .../stacks/OnlyQualityChanges.global.cfg | 8 --- tests/Settings/stacks/OnlyUser.extruder.cfg | 8 --- tests/Settings/stacks/OnlyUser.global.cfg | 8 --- .../Settings/stacks/OnlyVariant.extruder.cfg | 8 --- tests/Settings/stacks/OnlyVariant.global.cfg | 8 --- tests/conftest.py | 2 +- 23 files changed, 36 insertions(+), 231 deletions(-) delete mode 100644 tests/Settings/stacks/Complete.extruder.cfg delete mode 100644 tests/Settings/stacks/Complete.global.cfg delete mode 100644 tests/Settings/stacks/ExtruderLegacy.stack.cfg delete mode 100644 tests/Settings/stacks/Global.global.cfg delete mode 100644 tests/Settings/stacks/Global.stack.cfg delete mode 100644 tests/Settings/stacks/Left.extruder.cfg delete mode 100644 tests/Settings/stacks/MachineLegacy.stack.cfg delete mode 100644 tests/Settings/stacks/OnlyDefinition.extruder.cfg delete mode 100644 tests/Settings/stacks/OnlyDefinition.global.cfg delete mode 100644 tests/Settings/stacks/OnlyDefinitionChanges.global.cfg delete mode 100644 tests/Settings/stacks/OnlyMaterial.extruder.cfg delete mode 100644 tests/Settings/stacks/OnlyMaterial.global.cfg delete mode 100644 tests/Settings/stacks/OnlyQuality.extruder.cfg delete mode 100644 tests/Settings/stacks/OnlyQuality.global.cfg delete mode 100644 tests/Settings/stacks/OnlyQualityChanges.extruder.cfg delete mode 100644 tests/Settings/stacks/OnlyQualityChanges.global.cfg delete mode 100644 tests/Settings/stacks/OnlyUser.extruder.cfg delete mode 100644 tests/Settings/stacks/OnlyUser.global.cfg delete mode 100644 tests/Settings/stacks/OnlyVariant.extruder.cfg delete mode 100644 tests/Settings/stacks/OnlyVariant.global.cfg diff --git a/tests/Settings/TestCuraContainerRegistry.py b/tests/Settings/TestCuraContainerRegistry.py index dd78f2fd68..af478c3b2b 100644 --- a/tests/Settings/TestCuraContainerRegistry.py +++ b/tests/Settings/TestCuraContainerRegistry.py @@ -4,6 +4,7 @@ import os #To find the directory with test files and find the test files. import unittest.mock #To mock and monkeypatch stuff. +from UM.Settings.DefinitionContainer import DefinitionContainer from cura.Settings.ExtruderStack import ExtruderStack #Testing for returning the correct types of stacks. from cura.Settings.GlobalStack import GlobalStack #Testing for returning the correct types of stacks. import UM.Settings.InstanceContainer #Creating instance containers to register. @@ -17,36 +18,40 @@ def teardown(): os.remove(temporary_file) ## Tests whether addContainer properly converts to ExtruderStack. -def test_addContainerExtruderStack(container_registry, definition_container): +def test_addContainerExtruderStack(container_registry, definition_container, definition_changes_container): container_registry.addContainer(definition_container) + container_registry.addContainer(definition_changes_container) container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Extruder Stack") #A container we're going to convert. container_stack.setMetaDataEntry("type", "extruder_train") #This is now an extruder train. container_stack.insertContainer(0, definition_container) #Add a definition to it so it doesn't complain. + container_stack.insertContainer(1, definition_changes_container) mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered. with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container): container_registry.addContainer(container_stack) - assert len(mock_super_add_container.call_args_list) == 2 #Called only once. - assert len(mock_super_add_container.call_args_list[1][0]) == 1 #Called with one parameter. - assert type(mock_super_add_container.call_args_list[1][0][0]) == ExtruderStack + assert len(mock_super_add_container.call_args_list) == 1 #Called only once. + assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter. + assert type(mock_super_add_container.call_args_list[0][0][0]) == ExtruderStack ## Tests whether addContainer properly converts to GlobalStack. -def test_addContainerGlobalStack(container_registry, definition_container): +def test_addContainerGlobalStack(container_registry, definition_container, definition_changes_container): container_registry.addContainer(definition_container) + container_registry.addContainer(definition_changes_container) container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Global Stack") #A container we're going to convert. container_stack.setMetaDataEntry("type", "machine") #This is now a global stack. container_stack.insertContainer(0, definition_container) #Must have a definition. + container_stack.insertContainer(1, definition_changes_container) #Must have a definition changes. mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered. with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container): container_registry.addContainer(container_stack) - assert len(mock_super_add_container.call_args_list) == 2 #Called only once. - assert len(mock_super_add_container.call_args_list[1][0]) == 1 #Called with one parameter. - assert type(mock_super_add_container.call_args_list[1][0][0]) == GlobalStack + assert len(mock_super_add_container.call_args_list) == 1 #Called only once. + assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter. + assert type(mock_super_add_container.call_args_list[0][0][0]) == GlobalStack def test_addContainerGoodSettingVersion(container_registry, definition_container): from cura.CuraApplication import CuraApplication @@ -92,38 +97,3 @@ def test_addContainerBadSettingVersion(container_registry, definition_container) container_registry.addContainer(instance) mock_super_add_container.assert_not_called() #Should not get passed on to UM.Settings.ContainerRegistry.addContainer, because the setting_version doesn't match its definition! - -## Tests whether loading gives objects of the correct type. -# @pytest.mark.parametrize("filename, output_class", [ -# ("ExtruderLegacy.stack.cfg", ExtruderStack), -# ("MachineLegacy.stack.cfg", GlobalStack), -# ("Left.extruder.cfg", ExtruderStack), -# ("Global.global.cfg", GlobalStack), -# ("Global.stack.cfg", GlobalStack) -# ]) -# def test_loadTypes(filename, output_class, container_registry): -# #Mock some dependencies. -# Resources.getAllResourcesOfType = unittest.mock.MagicMock(return_value = [os.path.join(os.path.dirname(os.path.abspath(__file__)), "stacks", filename)]) #Return just this tested file. -# -# def findContainers(container_type = 0, id = None): -# if id == "some_instance": -# return [UM.Settings.ContainerRegistry._EmptyInstanceContainer(id)] -# elif id == "some_definition": -# return [DefinitionContainer(container_id = id)] -# else: -# return [] -# -# container_registry.findContainers = findContainers -# -# with unittest.mock.patch("cura.Settings.GlobalStack.GlobalStack.findContainer"): -# with unittest.mock.patch("os.remove"): -# container_registry.load() -# -# #Check whether the resulting type was correct. -# stack_id = filename.split(".")[0] -# for container_id, container in container_registry._containers.items(): #Stupid ContainerRegistry class doesn't expose any way of getting at this except by prodding the privates. -# if container_id == stack_id: #This is the one we're testing. -# assert type(container) == output_class -# break -# else: -# assert False #Container stack with specified ID was not loaded. diff --git a/tests/Settings/conftest.py b/tests/Settings/conftest.py index 8b519fd261..c2d8854f05 100644 --- a/tests/Settings/conftest.py +++ b/tests/Settings/conftest.py @@ -5,6 +5,8 @@ import pytest +from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.ContainerStack import setContainerRegistry from UM.Settings.DefinitionContainer import DefinitionContainer #To provide definition containers in the registry fixtures. from UM.Settings.InstanceContainer import InstanceContainer from cura.Settings.CuraContainerRegistry import CuraContainerRegistry @@ -15,29 +17,38 @@ import cura.Settings.CuraContainerStack # Returns the CuraContainerRegistry instance with some empty containers. @pytest.fixture() def container_registry(application) -> CuraContainerRegistry: - return application.getContainerRegistry() + ContainerRegistry._ContainerRegistry__instance= None # Need to reset since we only allow one instance + registry = CuraContainerRegistry(application) + setContainerRegistry(registry) + return registry # Gives an arbitrary definition container. @pytest.fixture() def definition_container() -> DefinitionContainer: return DefinitionContainer(container_id = "Test Definition") -#An empty global stack to test with. +# Gives an arbitrary definition changes container. @pytest.fixture() -def global_stack() -> GlobalStack: - global_stack = GlobalStack("TestGlobalStack") - # There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 - definition_changes_container = InstanceContainer(container_id = "InstanceContainer") +def definition_changes_container() -> InstanceContainer: + definition_changes_container = InstanceContainer(container_id = "Test Definition Changes") definition_changes_container.setMetaDataEntry("type", "definition_changes") + # Add current setting version to the instance container + from cura.CuraApplication import CuraApplication + definition_changes_container.getMetaData()["setting_version"] = CuraApplication.SettingVersion + return definition_changes_container + +# An empty global stack to test with. +# There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 +@pytest.fixture() +def global_stack(definition_changes_container) -> GlobalStack: + global_stack = GlobalStack("TestGlobalStack") global_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container return global_stack -## An empty extruder stack to test with. +# An empty extruder stack to test with. +# There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 @pytest.fixture() -def extruder_stack() -> ExtruderStack: +def extruder_stack(definition_changes_container) -> ExtruderStack: extruder_stack= ExtruderStack("TestExtruderStack") - # There is a restriction here that the definition changes cannot be an empty container. Added in CURA-5281 - definition_changes_container = InstanceContainer(container_id = "InstanceContainer") - definition_changes_container.setMetaDataEntry("type", "definition_changes") extruder_stack._containers[cura.Settings.CuraContainerStack._ContainerIndexes.DefinitionChanges] = definition_changes_container return extruder_stack \ No newline at end of file diff --git a/tests/Settings/stacks/Complete.extruder.cfg b/tests/Settings/stacks/Complete.extruder.cfg deleted file mode 100644 index 789c0978f3..0000000000 --- a/tests/Settings/stacks/Complete.extruder.cfg +++ /dev/null @@ -1,12 +0,0 @@ -[general] -version = 3 -name = Complete -id = Complete - -[containers] -0 = some_user_changes -1 = some_quality_changes -2 = some_quality -3 = some_material -4 = some_variant -5 = some_definition diff --git a/tests/Settings/stacks/Complete.global.cfg b/tests/Settings/stacks/Complete.global.cfg deleted file mode 100644 index f7f613991a..0000000000 --- a/tests/Settings/stacks/Complete.global.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[general] -version = 3 -name = Complete -id = Complete - -[containers] -0 = some_user_changes -1 = some_quality_changes -2 = some_quality -3 = some_material -4 = some_variant -5 = some_definition_changes -6 = some_definition diff --git a/tests/Settings/stacks/ExtruderLegacy.stack.cfg b/tests/Settings/stacks/ExtruderLegacy.stack.cfg deleted file mode 100644 index 4a6c419e40..0000000000 --- a/tests/Settings/stacks/ExtruderLegacy.stack.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -version = 3 -name = Legacy Extruder Stack -id = ExtruderLegacy - -[metadata] -type = extruder_train - -[containers] -3 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/Global.global.cfg b/tests/Settings/stacks/Global.global.cfg deleted file mode 100644 index 9034c1d0d0..0000000000 --- a/tests/Settings/stacks/Global.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Global -id = Global - -[containers] -3 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/Global.stack.cfg b/tests/Settings/stacks/Global.stack.cfg deleted file mode 100644 index aa1693d878..0000000000 --- a/tests/Settings/stacks/Global.stack.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -version = 3 -name = Global -id = Global - -[metadata] -type = machine - -[containers] -3 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/Left.extruder.cfg b/tests/Settings/stacks/Left.extruder.cfg deleted file mode 100644 index 8ba45d6754..0000000000 --- a/tests/Settings/stacks/Left.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Left -id = Left - -[containers] -3 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/MachineLegacy.stack.cfg b/tests/Settings/stacks/MachineLegacy.stack.cfg deleted file mode 100644 index 147d63c596..0000000000 --- a/tests/Settings/stacks/MachineLegacy.stack.cfg +++ /dev/null @@ -1,11 +0,0 @@ -[general] -version = 3 -name = Legacy Global Stack -id = MachineLegacy - -[metadata] -type = machine - -[containers] -3 = some_instance -6 = some_definition \ No newline at end of file diff --git a/tests/Settings/stacks/OnlyDefinition.extruder.cfg b/tests/Settings/stacks/OnlyDefinition.extruder.cfg deleted file mode 100644 index e58512b27f..0000000000 --- a/tests/Settings/stacks/OnlyDefinition.extruder.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[general] -version = 3 -name = Only Definition -id = OnlyDefinition - -[containers] -5 = some_definition diff --git a/tests/Settings/stacks/OnlyDefinition.global.cfg b/tests/Settings/stacks/OnlyDefinition.global.cfg deleted file mode 100644 index 9534353ed5..0000000000 --- a/tests/Settings/stacks/OnlyDefinition.global.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[general] -version = 3 -name = Only Definition -id = OnlyDefinition - -[containers] -6 = some_definition diff --git a/tests/Settings/stacks/OnlyDefinitionChanges.global.cfg b/tests/Settings/stacks/OnlyDefinitionChanges.global.cfg deleted file mode 100644 index 39e2105b7d..0000000000 --- a/tests/Settings/stacks/OnlyDefinitionChanges.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Definition Changes -id = OnlyDefinitionChanges - -[containers] -5 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyMaterial.extruder.cfg b/tests/Settings/stacks/OnlyMaterial.extruder.cfg deleted file mode 100644 index 49a9d12389..0000000000 --- a/tests/Settings/stacks/OnlyMaterial.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Material -id = OnlyMaterial - -[containers] -3 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyMaterial.global.cfg b/tests/Settings/stacks/OnlyMaterial.global.cfg deleted file mode 100644 index 715651a9b9..0000000000 --- a/tests/Settings/stacks/OnlyMaterial.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Material -id = OnlyMaterial - -[containers] -3 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyQuality.extruder.cfg b/tests/Settings/stacks/OnlyQuality.extruder.cfg deleted file mode 100644 index aaf7fb30c5..0000000000 --- a/tests/Settings/stacks/OnlyQuality.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality -id = OnlyQuality - -[containers] -2 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyQuality.global.cfg b/tests/Settings/stacks/OnlyQuality.global.cfg deleted file mode 100644 index f07a35666e..0000000000 --- a/tests/Settings/stacks/OnlyQuality.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality -id = OnlyQuality - -[containers] -2 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyQualityChanges.extruder.cfg b/tests/Settings/stacks/OnlyQualityChanges.extruder.cfg deleted file mode 100644 index 653bad840c..0000000000 --- a/tests/Settings/stacks/OnlyQualityChanges.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality Changes -id = OnlyQualityChanges - -[containers] -1 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyQualityChanges.global.cfg b/tests/Settings/stacks/OnlyQualityChanges.global.cfg deleted file mode 100644 index 17d279377a..0000000000 --- a/tests/Settings/stacks/OnlyQualityChanges.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Quality Changes -id = OnlyQualityChanges - -[containers] -1 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyUser.extruder.cfg b/tests/Settings/stacks/OnlyUser.extruder.cfg deleted file mode 100644 index abf812a859..0000000000 --- a/tests/Settings/stacks/OnlyUser.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only User -id = OnlyUser - -[containers] -0 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyUser.global.cfg b/tests/Settings/stacks/OnlyUser.global.cfg deleted file mode 100644 index 31371d2c51..0000000000 --- a/tests/Settings/stacks/OnlyUser.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only User -id = OnlyUser - -[containers] -0 = some_instance -6 = some_definition diff --git a/tests/Settings/stacks/OnlyVariant.extruder.cfg b/tests/Settings/stacks/OnlyVariant.extruder.cfg deleted file mode 100644 index a31997a6fd..0000000000 --- a/tests/Settings/stacks/OnlyVariant.extruder.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Variant -id = OnlyVariant - -[containers] -4 = some_instance -5 = some_definition diff --git a/tests/Settings/stacks/OnlyVariant.global.cfg b/tests/Settings/stacks/OnlyVariant.global.cfg deleted file mode 100644 index 158d533ac8..0000000000 --- a/tests/Settings/stacks/OnlyVariant.global.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[general] -version = 3 -name = Only Variant -id = OnlyVariant - -[containers] -4 = some_instance -6 = some_definition diff --git a/tests/conftest.py b/tests/conftest.py index d5bb5c8109..f2c709d8d8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -20,4 +20,4 @@ def application() -> CuraApplication: # Returns a MachineActionManager instance. @pytest.fixture() def machine_action_manager(application) -> MachineActionManager: - return application.getMachineActionManager() + return MachineActionManager(application) From 3a7fff42b5d8c07c1cd17b69e5170c69c2d8c001 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Wed, 15 Aug 2018 09:14:37 +0200 Subject: [PATCH 10/29] Fix code style. Contributes to CURA-5628. --- cura/OneAtATimeIterator.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/OneAtATimeIterator.py b/cura/OneAtATimeIterator.py index e7ad833e1c..a08f3ed2bf 100644 --- a/cura/OneAtATimeIterator.py +++ b/cura/OneAtATimeIterator.py @@ -76,6 +76,8 @@ class OneAtATimeIterator(Iterator): continue bounding_box = node.getBoundingBox() + if not bounding_box: + continue from UM.Math.Polygon import Polygon bounding_box_polygon = Polygon([[bounding_box.left, bounding_box.front], [bounding_box.left, bounding_box.back], From c20274e356f043e5a56393f5ae2647e48168b1fe Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 15 Aug 2018 11:04:09 +0200 Subject: [PATCH 11/29] Move constant instance containers to a separate file This way we separate the class/type definitions and the actual constants. --- cura/CuraApplication.py | 25 +++++---- cura/CuraEmptyInstanceContainers.py | 29 ---------- cura/Settings/CuraContainerStack.py | 13 ++--- .../cura_empty_instance_containers.py | 56 +++++++++++++++++++ tests/Settings/TestExtruderStack.py | 2 +- tests/Settings/TestGlobalStack.py | 3 +- 6 files changed, 78 insertions(+), 50 deletions(-) delete mode 100644 cura/CuraEmptyInstanceContainers.py create mode 100644 cura/Settings/cura_empty_instance_containers.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 908b718e1b..0d110ced54 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -104,7 +104,7 @@ from cura.Settings.ExtrudersModel import ExtrudersModel from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler from cura.Settings.ContainerManager import ContainerManager from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel -import cura.CuraEmptyInstanceContainers +import cura.Settings.cura_empty_instance_containers from cura.ObjectsModel import ObjectsModel @@ -368,22 +368,23 @@ class CuraApplication(QtApplication): # Add empty variant, material and quality containers. # Since they are empty, they should never be serialized and instead just programmatically created. # We need them to simplify the switching between materials. - self.empty_container = cura.CuraEmptyInstanceContainers.empty_container + self.empty_container = cura.Settings.cura_empty_instance_containers.empty_container - self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_definition_changes_container) - self.empty_definition_changes_container = cura.CuraEmptyInstanceContainers.empty_definition_changes_container + self._container_registry.addContainer( + cura.Settings.cura_empty_instance_containers.empty_definition_changes_container) + self.empty_definition_changes_container = cura.Settings.cura_empty_instance_containers.empty_definition_changes_container - self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_variant_container) - self.empty_variant_container = cura.CuraEmptyInstanceContainers.empty_variant_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_variant_container) + self.empty_variant_container = cura.Settings.cura_empty_instance_containers.empty_variant_container - self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_material_container) - self.empty_material_container = cura.CuraEmptyInstanceContainers.empty_material_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_material_container) + self.empty_material_container = cura.Settings.cura_empty_instance_containers.empty_material_container - self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_quality_container) - self.empty_quality_container = cura.CuraEmptyInstanceContainers.empty_quality_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_quality_container) + self.empty_quality_container = cura.Settings.cura_empty_instance_containers.empty_quality_container - self._container_registry.addContainer(cura.CuraEmptyInstanceContainers.empty_quality_changes_container) - self.empty_quality_changes_container = cura.CuraEmptyInstanceContainers.empty_quality_changes_container + self._container_registry.addContainer(cura.Settings.cura_empty_instance_containers.empty_quality_changes_container) + self.empty_quality_changes_container = cura.Settings.cura_empty_instance_containers.empty_quality_changes_container # Initializes the version upgrade manager with by providing the paths for each resource type and the latest # versions. diff --git a/cura/CuraEmptyInstanceContainers.py b/cura/CuraEmptyInstanceContainers.py deleted file mode 100644 index 3f5d3e7c59..0000000000 --- a/cura/CuraEmptyInstanceContainers.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2018 Ultimaker B.V. -# Cura is released under the terms of the LGPLv3 or higher. - -from UM.Settings.EmptyInstanceContainer import empty_container -import copy - -empty_definition_changes_container = copy.deepcopy(empty_container) -empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes") -empty_definition_changes_container.setMetaDataEntry("type", "definition_changes") - -empty_variant_container = copy.deepcopy(empty_container) -empty_variant_container.setMetaDataEntry("id", "empty_variant") -empty_variant_container.setMetaDataEntry("type", "variant") - -empty_material_container = copy.deepcopy(empty_container) -empty_material_container.setMetaDataEntry("id", "empty_material") -empty_material_container.setMetaDataEntry("type", "material") - -empty_quality_container = copy.deepcopy(empty_container) -empty_quality_container.setMetaDataEntry("id", "empty_quality") -empty_quality_container.setName("Not Supported") -empty_quality_container.setMetaDataEntry("quality_type", "not_supported") -empty_quality_container.setMetaDataEntry("type", "quality") -empty_quality_container.setMetaDataEntry("supported", False) - -empty_quality_changes_container = copy.deepcopy(empty_container) -empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes") -empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") -empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported") diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py index dabed97011..c8d1d9e370 100755 --- a/cura/Settings/CuraContainerStack.py +++ b/cura/Settings/CuraContainerStack.py @@ -13,8 +13,7 @@ from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.DefinitionContainer import DefinitionContainer from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.Interfaces import ContainerInterface, DefinitionContainerInterface -from UM.Settings.EmptyInstanceContainer import empty_container -from cura import CuraEmptyInstanceContainers +from cura.Settings import cura_empty_instance_containers from . import Exceptions @@ -41,12 +40,12 @@ class CuraContainerStack(ContainerStack): def __init__(self, container_id: str) -> None: super().__init__(container_id) - self._empty_instance_container = empty_container #type: InstanceContainer + self._empty_instance_container = cura_empty_instance_containers.empty_container #type: InstanceContainer - self._empty_quality_changes = CuraEmptyInstanceContainers.empty_quality_changes_container #type: InstanceContainer - self._empty_quality = CuraEmptyInstanceContainers.empty_quality_container #type: InstanceContainer - self._empty_material = CuraEmptyInstanceContainers.empty_material_container #type: InstanceContainer - self._empty_variant = CuraEmptyInstanceContainers.empty_variant_container #type: InstanceContainer + self._empty_quality_changes = cura_empty_instance_containers.empty_quality_changes_container #type: InstanceContainer + self._empty_quality = cura_empty_instance_containers.empty_quality_container #type: InstanceContainer + self._empty_material = cura_empty_instance_containers.empty_material_container #type: InstanceContainer + self._empty_variant = cura_empty_instance_containers.empty_variant_container #type: InstanceContainer self._containers = [self._empty_instance_container for i in range(len(_ContainerIndexes.IndexTypeMap))] #type: List[ContainerInterface] self._containers[_ContainerIndexes.QualityChanges] = self._empty_quality_changes diff --git a/cura/Settings/cura_empty_instance_containers.py b/cura/Settings/cura_empty_instance_containers.py new file mode 100644 index 0000000000..d76407ed79 --- /dev/null +++ b/cura/Settings/cura_empty_instance_containers.py @@ -0,0 +1,56 @@ +# Copyright (c) 2018 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +import copy + +from UM.Settings.constant_instance_containers import EMPTY_CONTAINER_ID, empty_container + + +# Empty definition changes +EMPTY_DEFINITION_CHANGES_CONTAINER_ID = "empty_definition_changes" +empty_definition_changes_container = copy.deepcopy(empty_container) +empty_definition_changes_container.setMetaDataEntry("id", EMPTY_DEFINITION_CHANGES_CONTAINER_ID) +empty_definition_changes_container.setMetaDataEntry("type", "definition_changes") + +# Empty variant +EMPTY_VARIANT_CONTAINER_ID = "empty_variant" +empty_variant_container = copy.deepcopy(empty_container) +empty_variant_container.setMetaDataEntry("id", EMPTY_VARIANT_CONTAINER_ID) +empty_variant_container.setMetaDataEntry("type", "variant") + +# Empty material +EMPTY_MATERIAL_CONTAINER_ID = "empty_material" +empty_material_container = copy.deepcopy(empty_container) +empty_material_container.setMetaDataEntry("id", EMPTY_MATERIAL_CONTAINER_ID) +empty_material_container.setMetaDataEntry("type", "material") + +# Empty quality +EMPTY_QUALITY_CONTAINER_ID = "empty_quality" +empty_quality_container = copy.deepcopy(empty_container) +empty_quality_container.setMetaDataEntry("id", EMPTY_QUALITY_CONTAINER_ID) +empty_quality_container.setName("Not Supported") +empty_quality_container.setMetaDataEntry("quality_type", "not_supported") +empty_quality_container.setMetaDataEntry("type", "quality") +empty_quality_container.setMetaDataEntry("supported", False) + +# Empty quality changes +EMPTY_QUALITY_CHANGES_CONTAINER_ID = "empty_quality_changes" +empty_quality_changes_container = copy.deepcopy(empty_container) +empty_quality_changes_container.setMetaDataEntry("id", EMPTY_QUALITY_CHANGES_CONTAINER_ID) +empty_quality_changes_container.setMetaDataEntry("type", "quality_changes") +empty_quality_changes_container.setMetaDataEntry("quality_type", "not_supported") + + +__all__ = ["EMPTY_CONTAINER_ID", + "empty_container", # For convenience + "EMPTY_DEFINITION_CHANGES_CONTAINER_ID", + "empty_definition_changes_container", + "EMPTY_VARIANT_CONTAINER_ID", + "empty_variant_container", + "EMPTY_MATERIAL_CONTAINER_ID", + "empty_material_container", + "EMPTY_QUALITY_CHANGES_CONTAINER_ID", + "empty_quality_changes_container", + "EMPTY_QUALITY_CONTAINER_ID", + "empty_quality_container" + ] diff --git a/tests/Settings/TestExtruderStack.py b/tests/Settings/TestExtruderStack.py index b2fa171068..df2e1075d1 100644 --- a/tests/Settings/TestExtruderStack.py +++ b/tests/Settings/TestExtruderStack.py @@ -9,9 +9,9 @@ import UM.Settings.ContainerRegistry #To create empty instance containers. import UM.Settings.ContainerStack #To set the container registry the container stacks use. from UM.Settings.DefinitionContainer import DefinitionContainer #To check against the class of DefinitionContainer. from UM.Settings.InstanceContainer import InstanceContainer #To check against the class of InstanceContainer. -from UM.Settings.EmptyInstanceContainer import empty_container from cura.Settings.Exceptions import InvalidContainerError, InvalidOperationError #To check whether the correct exceptions are raised. from cura.Settings.ExtruderManager import ExtruderManager +from cura.Settings.cura_empty_instance_containers import empty_container ## Gets an instance container with a specified container type. # diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py index 7aba53c4e5..f8052aa4bb 100755 --- a/tests/Settings/TestGlobalStack.py +++ b/tests/Settings/TestGlobalStack.py @@ -9,11 +9,12 @@ from cura.Settings.Exceptions import InvalidContainerError, InvalidOperationErro from UM.Settings.DefinitionContainer import DefinitionContainer #To test against the class DefinitionContainer. from UM.Settings.InstanceContainer import InstanceContainer #To test against the class InstanceContainer. from UM.Settings.SettingInstance import InstanceState -from UM.Settings.EmptyInstanceContainer import empty_container import UM.Settings.ContainerRegistry import UM.Settings.ContainerStack import UM.Settings.SettingDefinition #To add settings to the definition. +from cura.Settings.cura_empty_instance_containers import empty_container + ## Gets an instance container with a specified container type. # # \param container_type The type metadata for the instance container. From 6c1d380602ed9ff0fc901716d2376ff3969fb55b Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 16 Aug 2018 13:45:27 +0200 Subject: [PATCH 12/29] Renamed snap_distance to minimum_polygon_circumference and changed the description a bit. CURA-5623 --- resources/definitions/fdmprinter.def.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 8b3e4e1f05..4ea5f8a600 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5625,10 +5625,10 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "snap_distance": + "minimum_polygon_circumference": { - "label": "Snap Distance", - "description": "Snap distance between polygons in mm. Controls the polygons that may be filtered out when the model is sliced. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details.", + "label": "Minimum polygon circumference", + "description": "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details.", "unit": "mm", "type": "float", "default_value": 1.0, From 376b6a53c935035ac9dc1b0aab29360d9b18a762 Mon Sep 17 00:00:00 2001 From: Jack Ha Date: Thu, 16 Aug 2018 13:47:32 +0200 Subject: [PATCH 13/29] Capital Letters In Setting Name. CURA-5623 --- resources/definitions/fdmprinter.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index daf0af4d64..d26b2b03f4 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5628,7 +5628,7 @@ }, "minimum_polygon_circumference": { - "label": "Minimum polygon circumference", + "label": "Minimum Polygon Circumference", "description": "Polygons in sliced layers that have a circumference smaller than this amount will be filtered out. Lower values lead to higher resolution mesh at the cost of slicing time. It is meant mostly for high resolution SLA printers and very tiny 3D models with a lot of details.", "unit": "mm", "type": "float", From f42dc24d950df902cae9cf76dd817e7f2d13a9a2 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Thu, 16 Aug 2018 15:16:30 +0200 Subject: [PATCH 14/29] Do not show gcode.gz as an option in save file dialog CURA-5649 --- cura/CuraApplication.py | 20 -------------------- cura/Settings/GlobalStack.py | 4 ++++ plugins/GCodeGzWriter/__init__.py | 3 ++- resources/qml/SaveButton.qml | 4 +++- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 23a11a2bb3..dab3de3ab8 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -215,7 +215,6 @@ class CuraApplication(QtApplication): self._message_box_callback = None self._message_box_callback_arguments = [] - self._preferred_mimetype = "" self._i18n_catalog = None self._currently_loading_files = [] @@ -514,9 +513,6 @@ class CuraApplication(QtApplication): self.applicationShuttingDown.connect(self.saveSettings) self.engineCreatedSignal.connect(self._onEngineCreated) - self.globalContainerStackChanged.connect(self._onGlobalContainerChanged) - self._onGlobalContainerChanged() - self.getCuraSceneController().setActiveBuildPlate(0) # Initialize CuraApplication.Created = True @@ -997,30 +993,14 @@ class CuraApplication(QtApplication): self._camera_animation.setTarget(Selection.getSelectedObject(0).getWorldPosition()) self._camera_animation.start() - def _onGlobalContainerChanged(self): - if self._global_container_stack is not None: - machine_file_formats = [file_type.strip() for file_type in self._global_container_stack.getMetaDataEntry("file_formats").split(";")] - new_preferred_mimetype = "" - if machine_file_formats: - new_preferred_mimetype = machine_file_formats[0] - - if new_preferred_mimetype != self._preferred_mimetype: - self._preferred_mimetype = new_preferred_mimetype - self.preferredOutputMimetypeChanged.emit() - requestAddPrinter = pyqtSignal() activityChanged = pyqtSignal() sceneBoundingBoxChanged = pyqtSignal() - preferredOutputMimetypeChanged = pyqtSignal() @pyqtProperty(bool, notify = activityChanged) def platformActivity(self): return self._platform_activity - @pyqtProperty(str, notify=preferredOutputMimetypeChanged) - def preferredOutputMimetype(self): - return self._preferred_mimetype - @pyqtProperty(str, notify = sceneBoundingBoxChanged) def getSceneBoundingBoxString(self): return self._i18n_catalog.i18nc("@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm.", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()} diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index dda21f3719..36084b7d4d 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -61,6 +61,10 @@ class GlobalStack(CuraContainerStack): name = self.variant.getName() return name + @pyqtProperty(str, constant = True) + def preferred_output_file_formats(self) -> str: + return self.getMetaDataEntry("file_formats") + ## Add an extruder to the list of extruders of this stack. # # \param extruder The extruder to add. diff --git a/plugins/GCodeGzWriter/__init__.py b/plugins/GCodeGzWriter/__init__.py index e257bcb011..95949eee74 100644 --- a/plugins/GCodeGzWriter/__init__.py +++ b/plugins/GCodeGzWriter/__init__.py @@ -16,7 +16,8 @@ def getMetaData(): "extension": file_extension, "description": catalog.i18nc("@item:inlistbox", "Compressed G-code File"), "mime_type": "application/gzip", - "mode": GCodeGzWriter.GCodeGzWriter.OutputMode.BinaryMode + "mode": GCodeGzWriter.GCodeGzWriter.OutputMode.BinaryMode, + "hide_in_file_dialog": True, }] } } diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml index 0e0eec7277..2a0a523026 100644 --- a/resources/qml/SaveButton.qml +++ b/resources/qml/SaveButton.qml @@ -7,6 +7,7 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Layouts 1.1 import UM 1.1 as UM +import Cura 1.0 as Cura Item { id: base; @@ -257,7 +258,8 @@ Item { onClicked: { forceActiveFocus(); - UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, { "filter_by_machine": true, "preferred_mimetype":Printer.preferredOutputMimetype }); + UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, + { "filter_by_machine": true, "preferred_mimetypes": Cura.MachineManager.activeMachine.preferred_output_file_formats }); } style: ButtonStyle { From 31e283110f97189e7b5a38b025969fe25ed7e8e7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 17 Aug 2018 09:29:08 +0200 Subject: [PATCH 15/29] Check first if preferred quality exists Fixes #3784. --- cura/Settings/CuraStackBuilder.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index a794dde651..31ebc04de2 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -108,16 +108,20 @@ class CuraStackBuilder: preferred_quality_type = machine_definition.getMetaDataEntry("preferred_quality_type") quality_group_dict = quality_manager.getQualityGroups(new_global_stack) - quality_group = quality_group_dict.get(preferred_quality_type) + if quality_group_dict: #There are any quality profiles. + if preferred_quality_type not in quality_group_dict: + Logger.log("w", "The preferred quality {quality_type} doesn't exist for this set-up. Choosing a random one.".format(quality_type = preferred_quality_type)) + preferred_quality_type = next(iter(quality_group_dict)) + quality_group = quality_group_dict.get(preferred_quality_type) - new_global_stack.quality = quality_group.node_for_global.getContainer() - if not new_global_stack.quality: - new_global_stack.quality = application.empty_quality_container - for position, extruder_stack in new_global_stack.extruders.items(): - if position in quality_group.nodes_for_extruders and quality_group.nodes_for_extruders[position].getContainer(): - extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer() - else: - extruder_stack.quality = application.empty_quality_container + new_global_stack.quality = quality_group.node_for_global.getContainer() + if not new_global_stack.quality: + new_global_stack.quality = application.empty_quality_container + for position, extruder_stack in new_global_stack.extruders.items(): + if position in quality_group.nodes_for_extruders and quality_group.nodes_for_extruders[position].getContainer(): + extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer() + else: + extruder_stack.quality = application.empty_quality_container # Register the global stack after the extruder stacks are created. This prevents the registry from adding another # extruder stack because the global stack didn't have one yet (which is enforced since Cura 3.1). From 013032279db10b858b5bbd8b2115de762723665e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 17 Aug 2018 10:00:28 +0200 Subject: [PATCH 16/29] Better handling of no quality group in CuraStackBuilder --- cura/Settings/CuraStackBuilder.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 31ebc04de2..12fe732e3e 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -108,7 +108,14 @@ class CuraStackBuilder: preferred_quality_type = machine_definition.getMetaDataEntry("preferred_quality_type") quality_group_dict = quality_manager.getQualityGroups(new_global_stack) - if quality_group_dict: #There are any quality profiles. + if not quality_group_dict: + # There is no available quality group, set all quality containers to empty. + new_global_stack.quality = application.empty_quality_container + for extruder_stack in new_global_stack.extruders.values(): + extruder_stack.quality = application.empty_quality_container + else: + # Set the quality containers to the preferred quality type if available, otherwise use the first quality + # type that's available. if preferred_quality_type not in quality_group_dict: Logger.log("w", "The preferred quality {quality_type} doesn't exist for this set-up. Choosing a random one.".format(quality_type = preferred_quality_type)) preferred_quality_type = next(iter(quality_group_dict)) From 1079a9be2c72de8d4c32895701e9842e1521fd09 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Fri, 17 Aug 2018 10:53:01 +0200 Subject: [PATCH 17/29] Do not add saved gcodes to recent files list --- plugins/GCodeGzWriter/GCodeGzWriter.py | 4 ++++ plugins/GCodeWriter/GCodeWriter.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/GCodeGzWriter/GCodeGzWriter.py b/plugins/GCodeGzWriter/GCodeGzWriter.py index e191a9c427..cbbfb8f986 100644 --- a/plugins/GCodeGzWriter/GCodeGzWriter.py +++ b/plugins/GCodeGzWriter/GCodeGzWriter.py @@ -17,6 +17,10 @@ catalog = i18nCatalog("cura") # # If you're zipping g-code, you might as well use gzip! class GCodeGzWriter(MeshWriter): + + def __init__(self) -> None: + super().__init__(add_to_recent_files = False) + ## Writes the gzipped g-code to a stream. # # Note that even though the function accepts a collection of nodes, the diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 59e9a29691..5d5e3578cd 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -47,7 +47,7 @@ class GCodeWriter(MeshWriter): _setting_keyword = ";SETTING_" def __init__(self): - super().__init__() + super().__init__(add_to_recent_files = False) self._application = Application.getInstance() From 284f90f3ff7ec3422fe490d1bd0942f506fc35af Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 17 Aug 2018 09:57:37 +0200 Subject: [PATCH 18/29] Fix camera position before adding a printer Don't use the diagonal size then, because that returns 0. --- cura/CuraApplication.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 23a11a2bb3..ef59d5a7f6 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -780,7 +780,10 @@ class CuraApplication(QtApplication): # Initialize camera root = controller.getScene().getRoot() camera = Camera("3d", root) - camera.setPosition(Vector(-80, 250, 700) * self.getBuildVolume().getDiagonalSize() / 375) + diagonal = self.getBuildVolume().getDiagonalSize() + if diagonal < 1: #No printer added yet. Set a default camera distance for normal-sized printers. + diagonal = 375 + camera.setPosition(Vector(-80, 250, 700) * diagonal / 375) camera.setPerspective(True) camera.lookAt(Vector(0, 0, 0)) controller.getScene().setActiveCamera("3d") From 9f190590b1e5ceac0fcd0942bfcf39807071d617 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 17 Aug 2018 10:56:29 +0200 Subject: [PATCH 19/29] Only change camera range if camera range is valid This was a debugging test to see if this fixed an issue. It turned out to not be the issue in question, but this is still a defensive coding thing that would be good to have. --- cura/BuildVolume.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index 5aa3873c89..a25552aac5 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -561,7 +561,9 @@ class BuildVolume(SceneNode): camera = Application.getInstance().getController().getCameraTool() if camera: - camera.setZoomRange(min = 1, max = self.getDiagonalSize() * 5) #You can zoom out up to 5 times the diagonal. This gives some space around the volume. + diagonal = self.getDiagonalSize() + if diagonal > 1: + camera.setZoomRange(min = 0.1, max = diagonal * 5) #You can zoom out up to 5 times the diagonal. This gives some space around the volume. def _onEngineCreated(self): self._engine_ready = True From 6740c2bee9a0732daf77224cd4ef34f0eb736364 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Fri, 17 Aug 2018 11:24:39 +0200 Subject: [PATCH 20/29] Fix offset of initial layer height It would detect the height of the raft by looking at what the first Z coordinate is that it encounters on layer 0. This Z coordinate also includes the initial layer height though. If you pause lower than the initial layer height (but higher than 0), you'd expect to pause in the initial layer. --- plugins/PostProcessingPlugin/scripts/PauseAtHeight.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py index 6354dd4f04..8b50a88b7f 100644 --- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py +++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py @@ -28,7 +28,7 @@ class PauseAtHeight(Script): "pause_height": { "label": "Pause Height", - "description": "At what height should the pause occur", + "description": "At what height should the pause occur?", "unit": "mm", "type": "float", "default_value": 5.0, @@ -39,7 +39,7 @@ class PauseAtHeight(Script): "pause_layer": { "label": "Pause Layer", - "description": "At what layer should the pause occur", + "description": "At what layer should the pause occur?", "type": "int", "value": "math.floor((pause_height - 0.27) / 0.1) + 1", "minimum_value": "0", @@ -142,13 +142,14 @@ class PauseAtHeight(Script): standby_temperature = self.getSettingValueByKey("standby_temperature") firmware_retract = Application.getInstance().getGlobalContainerStack().getProperty("machine_firmware_retract", "value") control_temperatures = Application.getInstance().getGlobalContainerStack().getProperty("machine_nozzle_temp_enabled", "value") + initial_layer_height = Application.getInstance().getGlobalContainerStack().getProperty("layer_height_0", "value") is_griffin = False # T = ExtruderManager.getInstance().getActiveExtruderStack().getProperty("material_print_temperature", "value") # use offset to calculate the current height: = - - layer_0_z = 0. + layer_0_z = 0 current_z = 0 got_first_g_cmd_on_layer_0 = False current_t = 0 #Tracks the current extruder for tracking the target temperature. @@ -195,11 +196,10 @@ class PauseAtHeight(Script): # This block is executed once, the first time there is a G # command, to get the z offset (z for first positive layer) if not got_first_g_cmd_on_layer_0: - layer_0_z = current_z + layer_0_z = current_z - initial_layer_height got_first_g_cmd_on_layer_0 = True current_height = current_z - layer_0_z - if current_height < pause_height: break # Try the next layer. From 1468ac1d59ec4fbf4472c03b7d7a727c636c2a6e Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Mon, 20 Aug 2018 13:19:49 +0200 Subject: [PATCH 21/29] Check if dict has key before accessing in BuildVolume --- cura/BuildVolume.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py index a25552aac5..b029665abd 100755 --- a/cura/BuildVolume.py +++ b/cura/BuildVolume.py @@ -242,6 +242,8 @@ class BuildVolume(SceneNode): # Mark the node as outside build volume if the set extruder is disabled extruder_position = node.callDecoration("getActiveExtruderPosition") + if extruder_position not in self._global_container_stack.extruders: + continue if not self._global_container_stack.extruders[extruder_position].isEnabled: node.setOutsideBuildArea(True) continue From ca25638c07d699002980dab7564a9b5743582b50 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 21 Aug 2018 11:01:35 +0200 Subject: [PATCH 22/29] .ufp should also not show up in recent files since it's a gcode format --- .pytest_cache/README.md | 8 +++ .pytest_cache/v/cache/lastfailed | 100 +++++++++++++++++++++++++++++++ .pytest_cache/v/cache/nodeids | 3 + plugins/UFPWriter/UFPWriter.py | 2 +- 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 .pytest_cache/README.md create mode 100644 .pytest_cache/v/cache/lastfailed create mode 100644 .pytest_cache/v/cache/nodeids diff --git a/.pytest_cache/README.md b/.pytest_cache/README.md new file mode 100644 index 0000000000..bb78ba07ee --- /dev/null +++ b/.pytest_cache/README.md @@ -0,0 +1,8 @@ +# pytest cache directory # + +This directory contains data from the pytest's cache plugin, +which provides the `--lf` and `--ff` options, as well as the `cache` fixture. + +**Do not** commit this to version control. + +See [the docs](https://docs.pytest.org/en/latest/cache.html) for more information. diff --git a/.pytest_cache/v/cache/lastfailed b/.pytest_cache/v/cache/lastfailed new file mode 100644 index 0000000000..adb96c8331 --- /dev/null +++ b/.pytest_cache/v/cache/lastfailed @@ -0,0 +1,100 @@ +{ + "tests/Settings/TestCuraContainerRegistry.py::test_addContainerBadSettingVersion": true, + "tests/Settings/TestCuraContainerRegistry.py::test_addContainerExtruderStack": true, + "tests/Settings/TestCuraContainerRegistry.py::test_addContainerGlobalStack": true, + "tests/Settings/TestCuraContainerRegistry.py::test_addContainerGoodSettingVersion": true, + "tests/Settings/TestCuraContainerRegistry.py::test_addContainerNoSettingVersion": true, + "tests/Settings/TestExtruderStack.py::test_addContainer": true, + "tests/Settings/TestExtruderStack.py::test_constrainDefinitionValid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainDefinitionValid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainMaterialInvalid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainMaterialInvalid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainMaterialInvalid[container2]": true, + "tests/Settings/TestExtruderStack.py::test_constrainMaterialValid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainMaterialValid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesInvalid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesInvalid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesInvalid[container2]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesValid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesValid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityInvalid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityInvalid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityInvalid[container2]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityValid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainQualityValid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainUserChangesInvalid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainUserChangesInvalid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainUserChangesInvalid[container2]": true, + "tests/Settings/TestExtruderStack.py::test_constrainUserChangesValid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainUserChangesValid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainVariantInvalid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainVariantInvalid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_constrainVariantValid[container0]": true, + "tests/Settings/TestExtruderStack.py::test_constrainVariantValid[container1]": true, + "tests/Settings/TestExtruderStack.py::test_deserializeMoveInstanceContainer": true, + "tests/Settings/TestExtruderStack.py::test_deserializeRemovesWrongContainerClass": true, + "tests/Settings/TestExtruderStack.py::test_deserializeRemovesWrongInstanceContainer": true, + "tests/Settings/TestExtruderStack.py::test_deserializeWrongDefinitionClass": true, + "tests/Settings/TestExtruderStack.py::test_getPropertyFallThrough": true, + "tests/Settings/TestExtruderStack.py::test_insertContainer": true, + "tests/Settings/TestExtruderStack.py::test_removeContainer": true, + "tests/Settings/TestExtruderStack.py::test_setPropertyUser[foo-value-100]": true, + "tests/Settings/TestExtruderStack.py::test_setPropertyUser[layer_height-default_value-0.1337]": true, + "tests/Settings/TestExtruderStack.py::test_setPropertyUser[layer_height-is_bright_pink-of course]": true, + "tests/Settings/TestExtruderStack.py::test_setPropertyUser[layer_height-value-0.1337]": true, + "tests/Settings/TestExtruderStack.py::test_setPropertyUser[support_enabled-value-True]": true, + "tests/Settings/TestGlobalStack.py::test_addContainer": true, + "tests/Settings/TestGlobalStack.py::test_addExtruder": true, + "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesInvalid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesInvalid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesInvalid[container2]": true, + "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesValid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesValid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainDefinitionValid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainDefinitionValid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainMaterialInvalid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainMaterialInvalid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainMaterialInvalid[container2]": true, + "tests/Settings/TestGlobalStack.py::test_constrainMaterialValid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainMaterialValid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesInvalid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesInvalid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesInvalid[container2]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesValid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesValid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityInvalid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityInvalid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityInvalid[container2]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityValid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainQualityValid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainUserChangesInvalid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainUserChangesInvalid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainUserChangesInvalid[container2]": true, + "tests/Settings/TestGlobalStack.py::test_constrainUserChangesValid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainUserChangesValid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainVariantInvalid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainVariantInvalid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_constrainVariantValid[container0]": true, + "tests/Settings/TestGlobalStack.py::test_constrainVariantValid[container1]": true, + "tests/Settings/TestGlobalStack.py::test_deserializeMoveInstanceContainer": true, + "tests/Settings/TestGlobalStack.py::test_deserializeRemovesWrongContainerClass": true, + "tests/Settings/TestGlobalStack.py::test_deserializeRemovesWrongInstanceContainer": true, + "tests/Settings/TestGlobalStack.py::test_deserializeWrongDefinitionClass": true, + "tests/Settings/TestGlobalStack.py::test_getPropertyFallThrough": true, + "tests/Settings/TestGlobalStack.py::test_getPropertyInstancesBeforeResolve": true, + "tests/Settings/TestGlobalStack.py::test_getPropertyNoResolveInDefinition": true, + "tests/Settings/TestGlobalStack.py::test_getPropertyResolveInDefinition": true, + "tests/Settings/TestGlobalStack.py::test_getPropertyResolveInInstance": true, + "tests/Settings/TestGlobalStack.py::test_hasNoUserValue": true, + "tests/Settings/TestGlobalStack.py::test_hasUserValueQualityChanges": true, + "tests/Settings/TestGlobalStack.py::test_hasUserValueUserChanges": true, + "tests/Settings/TestGlobalStack.py::test_insertContainer": true, + "tests/Settings/TestGlobalStack.py::test_removeContainer": true, + "tests/Settings/TestGlobalStack.py::test_setNextStack": true, + "tests/Settings/TestGlobalStack.py::test_setPropertyUser[foo-value-100]": true, + "tests/Settings/TestGlobalStack.py::test_setPropertyUser[layer_height-default_value-0.1337]": true, + "tests/Settings/TestGlobalStack.py::test_setPropertyUser[layer_height-is_bright_pink-of course]": true, + "tests/Settings/TestGlobalStack.py::test_setPropertyUser[layer_height-value-0.1337]": true, + "tests/Settings/TestGlobalStack.py::test_setPropertyUser[support_enabled-value-True]": true, + "tests/TestMachineAction.py::test_addMachineAction": true +} \ No newline at end of file diff --git a/.pytest_cache/v/cache/nodeids b/.pytest_cache/v/cache/nodeids new file mode 100644 index 0000000000..d548ce2ff2 --- /dev/null +++ b/.pytest_cache/v/cache/nodeids @@ -0,0 +1,3 @@ +[ + "plugins/VersionUpgrade/VersionUpgrade34to40/tests/TestVersionUpgrade34to40.py::test_upgradeVersionNr[Empty config file-[general]\\n version = 5\\n [metadata]\\n setting_version = 4\\n]" +] \ No newline at end of file diff --git a/plugins/UFPWriter/UFPWriter.py b/plugins/UFPWriter/UFPWriter.py index 9344bf54da..ceb9d79087 100644 --- a/plugins/UFPWriter/UFPWriter.py +++ b/plugins/UFPWriter/UFPWriter.py @@ -20,7 +20,7 @@ catalog = i18nCatalog("cura") class UFPWriter(MeshWriter): def __init__(self): - super().__init__() + super().__init__(add_to_recent_files = False) self._snapshot = None Application.getInstance().getOutputDeviceManager().writeStarted.connect(self._createSnapshot) From 4635c8117d9085925904d66913ce13a9636c092e Mon Sep 17 00:00:00 2001 From: Aleksei S Date: Tue, 21 Aug 2018 11:49:13 +0200 Subject: [PATCH 23/29] Add changed_settings(retraction_combing) to Version Upgrade Cura3.4 CURA-5505 --- .../VersionUpgrade34to40/VersionUpgrade34to40.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py b/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py index 83609206ef..a61aae06bb 100644 --- a/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py +++ b/plugins/VersionUpgrade/VersionUpgrade34to40/VersionUpgrade34to40.py @@ -8,6 +8,9 @@ from UM.VersionUpgrade import VersionUpgrade deleted_settings = {"prime_tower_wall_thickness", "dual_pre_wipe", "prime_tower_purge_volume"} +changed_settings = {'retraction_combing': 'noskin'} +updated_settings = {'retraction_combing': 'infill'} + _RENAMED_MATERIAL_PROFILES = { "dsm_arnitel2045_175_cartesio_0.25_mm": "dsm_arnitel2045_175_cartesio_0.25mm_thermoplastic_extruder", "dsm_arnitel2045_175_cartesio_0.4_mm": "dsm_arnitel2045_175_cartesio_0.4mm_thermoplastic_extruder", @@ -127,6 +130,13 @@ class VersionUpgrade34to40(VersionUpgrade): continue del parser["values"][deleted_setting] + for setting_key in changed_settings: + if setting_key not in parser["values"]: + continue + + if parser["values"][setting_key] == changed_settings[setting_key]: + parser["values"][setting_key] = updated_settings[setting_key] + result = io.StringIO() parser.write(result) return [filename], [result.getvalue()] From 10e474ad27929b9d4a0dc799f5fcfba8c2251312 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 21 Aug 2018 13:38:54 +0200 Subject: [PATCH 24/29] Add draft shield distance into the prime tower position fomulas CURA-5644 --- resources/definitions/fdmprinter.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index c0c7e44d97..3eb7cb1c32 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -5074,7 +5074,7 @@ "unit": "mm", "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 200, - "value": "machine_width - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - 1", + "value": "machine_width - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1", "maximum_value": "machine_width / 2 if machine_center_is_zero else machine_width", "minimum_value": "resolveOrValue('prime_tower_size') - machine_width / 2 if machine_center_is_zero else resolveOrValue('prime_tower_size')", "settable_per_mesh": false, @@ -5088,7 +5088,7 @@ "unit": "mm", "enabled": "resolveOrValue('prime_tower_enable')", "default_value": 200, - "value": "machine_depth - prime_tower_size - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - 1", + "value": "machine_depth - prime_tower_size - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 - (resolveOrValue('draft_shield_dist') if resolveOrValue('draft_shield_enabled') else 0) - 1", "maximum_value": "machine_depth / 2 - resolveOrValue('prime_tower_size') if machine_center_is_zero else machine_depth - resolveOrValue('prime_tower_size')", "minimum_value": "machine_depth / -2 if machine_center_is_zero else 0", "settable_per_mesh": false, From f35005c8bafe238ff36b079b28f845bd9227047b Mon Sep 17 00:00:00 2001 From: Cherubim Date: Tue, 21 Aug 2018 14:24:07 +0200 Subject: [PATCH 25/29] Brackets on new line As per our code style. --- resources/qml/Preferences/MaterialView.qml | 47 ++++++++++++++-------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index 0929f1790a..97184ab558 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -30,20 +30,24 @@ TabView property bool reevaluateLinkedMaterials: false property string linkedMaterialNames: { - if (reevaluateLinkedMaterials) { + if (reevaluateLinkedMaterials) + { reevaluateLinkedMaterials = false; } - if (!base.containerId || !base.editingEnabled) { + if (!base.containerId || !base.editingEnabled) + { return "" } var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentMaterialNode, true); - if (linkedMaterials.length == 0) { + if (linkedMaterials.length == 0) + { return "" } return linkedMaterials.join(", "); } - function getApproximateDiameter(diameter) { + function getApproximateDiameter(diameter) + { return Math.round(diameter); } @@ -154,13 +158,15 @@ TabView } Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") } - Row { + Row + { width: scrollView.columnWidth height: parent.rowHeight spacing: Math.round(UM.Theme.getSize("default_margin").width / 2) // color indicator square - Rectangle { + Rectangle + { id: colorSelector color: properties.color_code @@ -171,7 +177,8 @@ TabView anchors.verticalCenter: parent.verticalCenter // open the color selection dialog on click - MouseArea { + MouseArea + { anchors.fill: parent onClicked: colorDialog.open() enabled: base.editingEnabled @@ -179,7 +186,8 @@ TabView } // pretty color name text field - ReadOnlyTextField { + ReadOnlyTextField + { id: colorLabel; text: properties.color_name; readOnly: !base.editingEnabled @@ -188,7 +196,8 @@ TabView // popup dialog to select a new color // if successful it sets the properties.color_code value to the new color - ColorDialog { + ColorDialog + { id: colorDialog color: properties.color_code onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color) @@ -258,7 +267,8 @@ TabView decimals: 2 maximumValue: 100000000 - onValueChanged: { + onValueChanged: + { base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value)) updateCostPerMeter() } @@ -275,7 +285,8 @@ TabView decimals: 0 maximumValue: 10000 - onValueChanged: { + onValueChanged: + { base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value)) updateCostPerMeter() } @@ -401,7 +412,8 @@ TabView { id: spinBox anchors.left: label.right - value: { + value: + { // In case the setting is not in the material... if (!isNaN(parseFloat(materialPropertyProvider.properties.value))) { @@ -493,8 +505,10 @@ TabView } // Tiny convenience function to check if a value really changed before trying to set it. - function setMetaDataEntry(entry_name, old_value, new_value) { - if (old_value != new_value) { + function setMetaDataEntry(entry_name, old_value, new_value) + { + if (old_value != new_value) + { Cura.ContainerManager.setContainerMetaDataEntry(base.currentMaterialNode, entry_name, new_value) // make sure the UI properties are updated as well since we don't re-fetch the entire model here // When the entry_name is something like properties/diameter, we take the last part of the entry_name @@ -546,10 +560,11 @@ TabView } // update the display name of the material - function updateMaterialDisplayName (old_name, new_name) + function updateMaterialDisplayName(old_name, new_name) { // don't change when new name is the same - if (old_name == new_name) { + if (old_name == new_name) + { return; } From af64d91587c4363ca30a9ed38d0ce03eeae701ed Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 21 Aug 2018 16:07:16 +0200 Subject: [PATCH 26/29] Fix stack handling in project loading CURA-5663 --- plugins/3MFReader/ThreeMFWorkspaceReader.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index e33b88375e..16ab22473b 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -630,6 +630,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader): type = "extruder_train") extruder_stack_dict = {stack.getMetaDataEntry("position"): stack for stack in extruder_stacks} + # Make sure that those extruders have the global stack as the next stack or later some value evaluation + # will fail. + for stack in extruder_stacks: + stack.setNextStack(global_stack, connect_signals = False) + Logger.log("d", "Workspace loading is checking definitions...") # Get all the definition files & check if they exist. If not, add them. definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)] From 94ce9205c3fc10f69c7508a189ca3a9641a4b123 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 22 Aug 2018 13:30:59 +0200 Subject: [PATCH 27/29] Remove pytest cache --- .gitignore | 1 + .pytest_cache/README.md | 8 --- .pytest_cache/v/cache/lastfailed | 100 ------------------------------- .pytest_cache/v/cache/nodeids | 3 - 4 files changed, 1 insertion(+), 111 deletions(-) delete mode 100644 .pytest_cache/README.md delete mode 100644 .pytest_cache/v/cache/lastfailed delete mode 100644 .pytest_cache/v/cache/nodeids diff --git a/.gitignore b/.gitignore index 98eaa6f414..5cc60c2f4c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ LC_MESSAGES .cache *.qmlc .mypy_cache +.pytest_cache #MacOS .DS_Store diff --git a/.pytest_cache/README.md b/.pytest_cache/README.md deleted file mode 100644 index bb78ba07ee..0000000000 --- a/.pytest_cache/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# pytest cache directory # - -This directory contains data from the pytest's cache plugin, -which provides the `--lf` and `--ff` options, as well as the `cache` fixture. - -**Do not** commit this to version control. - -See [the docs](https://docs.pytest.org/en/latest/cache.html) for more information. diff --git a/.pytest_cache/v/cache/lastfailed b/.pytest_cache/v/cache/lastfailed deleted file mode 100644 index adb96c8331..0000000000 --- a/.pytest_cache/v/cache/lastfailed +++ /dev/null @@ -1,100 +0,0 @@ -{ - "tests/Settings/TestCuraContainerRegistry.py::test_addContainerBadSettingVersion": true, - "tests/Settings/TestCuraContainerRegistry.py::test_addContainerExtruderStack": true, - "tests/Settings/TestCuraContainerRegistry.py::test_addContainerGlobalStack": true, - "tests/Settings/TestCuraContainerRegistry.py::test_addContainerGoodSettingVersion": true, - "tests/Settings/TestCuraContainerRegistry.py::test_addContainerNoSettingVersion": true, - "tests/Settings/TestExtruderStack.py::test_addContainer": true, - "tests/Settings/TestExtruderStack.py::test_constrainDefinitionValid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainDefinitionValid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainMaterialInvalid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainMaterialInvalid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainMaterialInvalid[container2]": true, - "tests/Settings/TestExtruderStack.py::test_constrainMaterialValid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainMaterialValid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesInvalid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesInvalid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesInvalid[container2]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesValid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityChangesValid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityInvalid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityInvalid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityInvalid[container2]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityValid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainQualityValid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainUserChangesInvalid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainUserChangesInvalid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainUserChangesInvalid[container2]": true, - "tests/Settings/TestExtruderStack.py::test_constrainUserChangesValid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainUserChangesValid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainVariantInvalid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainVariantInvalid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_constrainVariantValid[container0]": true, - "tests/Settings/TestExtruderStack.py::test_constrainVariantValid[container1]": true, - "tests/Settings/TestExtruderStack.py::test_deserializeMoveInstanceContainer": true, - "tests/Settings/TestExtruderStack.py::test_deserializeRemovesWrongContainerClass": true, - "tests/Settings/TestExtruderStack.py::test_deserializeRemovesWrongInstanceContainer": true, - "tests/Settings/TestExtruderStack.py::test_deserializeWrongDefinitionClass": true, - "tests/Settings/TestExtruderStack.py::test_getPropertyFallThrough": true, - "tests/Settings/TestExtruderStack.py::test_insertContainer": true, - "tests/Settings/TestExtruderStack.py::test_removeContainer": true, - "tests/Settings/TestExtruderStack.py::test_setPropertyUser[foo-value-100]": true, - "tests/Settings/TestExtruderStack.py::test_setPropertyUser[layer_height-default_value-0.1337]": true, - "tests/Settings/TestExtruderStack.py::test_setPropertyUser[layer_height-is_bright_pink-of course]": true, - "tests/Settings/TestExtruderStack.py::test_setPropertyUser[layer_height-value-0.1337]": true, - "tests/Settings/TestExtruderStack.py::test_setPropertyUser[support_enabled-value-True]": true, - "tests/Settings/TestGlobalStack.py::test_addContainer": true, - "tests/Settings/TestGlobalStack.py::test_addExtruder": true, - "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesInvalid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesInvalid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesInvalid[container2]": true, - "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesValid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainDefinitionChangesValid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainDefinitionValid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainDefinitionValid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainMaterialInvalid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainMaterialInvalid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainMaterialInvalid[container2]": true, - "tests/Settings/TestGlobalStack.py::test_constrainMaterialValid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainMaterialValid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesInvalid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesInvalid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesInvalid[container2]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesValid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityChangesValid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityInvalid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityInvalid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityInvalid[container2]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityValid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainQualityValid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainUserChangesInvalid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainUserChangesInvalid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainUserChangesInvalid[container2]": true, - "tests/Settings/TestGlobalStack.py::test_constrainUserChangesValid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainUserChangesValid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainVariantInvalid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainVariantInvalid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_constrainVariantValid[container0]": true, - "tests/Settings/TestGlobalStack.py::test_constrainVariantValid[container1]": true, - "tests/Settings/TestGlobalStack.py::test_deserializeMoveInstanceContainer": true, - "tests/Settings/TestGlobalStack.py::test_deserializeRemovesWrongContainerClass": true, - "tests/Settings/TestGlobalStack.py::test_deserializeRemovesWrongInstanceContainer": true, - "tests/Settings/TestGlobalStack.py::test_deserializeWrongDefinitionClass": true, - "tests/Settings/TestGlobalStack.py::test_getPropertyFallThrough": true, - "tests/Settings/TestGlobalStack.py::test_getPropertyInstancesBeforeResolve": true, - "tests/Settings/TestGlobalStack.py::test_getPropertyNoResolveInDefinition": true, - "tests/Settings/TestGlobalStack.py::test_getPropertyResolveInDefinition": true, - "tests/Settings/TestGlobalStack.py::test_getPropertyResolveInInstance": true, - "tests/Settings/TestGlobalStack.py::test_hasNoUserValue": true, - "tests/Settings/TestGlobalStack.py::test_hasUserValueQualityChanges": true, - "tests/Settings/TestGlobalStack.py::test_hasUserValueUserChanges": true, - "tests/Settings/TestGlobalStack.py::test_insertContainer": true, - "tests/Settings/TestGlobalStack.py::test_removeContainer": true, - "tests/Settings/TestGlobalStack.py::test_setNextStack": true, - "tests/Settings/TestGlobalStack.py::test_setPropertyUser[foo-value-100]": true, - "tests/Settings/TestGlobalStack.py::test_setPropertyUser[layer_height-default_value-0.1337]": true, - "tests/Settings/TestGlobalStack.py::test_setPropertyUser[layer_height-is_bright_pink-of course]": true, - "tests/Settings/TestGlobalStack.py::test_setPropertyUser[layer_height-value-0.1337]": true, - "tests/Settings/TestGlobalStack.py::test_setPropertyUser[support_enabled-value-True]": true, - "tests/TestMachineAction.py::test_addMachineAction": true -} \ No newline at end of file diff --git a/.pytest_cache/v/cache/nodeids b/.pytest_cache/v/cache/nodeids deleted file mode 100644 index d548ce2ff2..0000000000 --- a/.pytest_cache/v/cache/nodeids +++ /dev/null @@ -1,3 +0,0 @@ -[ - "plugins/VersionUpgrade/VersionUpgrade34to40/tests/TestVersionUpgrade34to40.py::test_upgradeVersionNr[Empty config file-[general]\\n version = 5\\n [metadata]\\n setting_version = 4\\n]" -] \ No newline at end of file From 29180740de7100f58853556ce8603c54d2741f58 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Wed, 22 Aug 2018 13:36:17 +0200 Subject: [PATCH 28/29] Fix missed names --- resources/qml/Cura.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 60f6e77ea9..046a887a71 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -120,7 +120,7 @@ UM.MainWindow text: catalog.i18nc("@title:menu menubar:file","&Save...") onTriggered: { - var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetype": "application/x-curaproject+xml" }; + var args = { "filter_by_machine": false, "file_type": "workspace", "preferred_mimetypes": "application/x-curaproject+xml" }; if(UM.Preferences.getValue("cura/dialog_on_project_save")) { saveWorkspaceDialog.args = args; @@ -142,7 +142,7 @@ UM.MainWindow onTriggered: { var localDeviceId = "local_file"; - UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetype": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}); + UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}); } } @@ -151,7 +151,7 @@ UM.MainWindow text: catalog.i18nc("@action:inmenu menubar:file", "Export Selection..."); enabled: UM.Selection.hasSelection; iconName: "document-save-as"; - onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetype": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}); + onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetypes": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"}); } MenuSeparator { } From 49e3c23d1438c7133e739af62b23f5f9297313b1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 22 Aug 2018 16:53:27 +0200 Subject: [PATCH 29/29] Brackets on new line As per our code style. --- plugins/SimulationView/SimulationView.qml | 240 +++++++++++++++------- 1 file changed, 161 insertions(+), 79 deletions(-) diff --git a/plugins/SimulationView/SimulationView.qml b/plugins/SimulationView/SimulationView.qml index a3a8ced4cf..be767e93ab 100644 --- a/plugins/SimulationView/SimulationView.qml +++ b/plugins/SimulationView/SimulationView.qml @@ -1,4 +1,4 @@ -// Copyright (c) 2017 Ultimaker B.V. +// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.4 @@ -12,30 +12,43 @@ import Cura 1.0 as Cura Item { id: base - width: { - if (UM.SimulationView.compatibilityMode) { + width: + { + if (UM.SimulationView.compatibilityMode) + { return UM.Theme.getSize("layerview_menu_size_compatibility").width; - } else { + } + else + { return UM.Theme.getSize("layerview_menu_size").width; } } height: { - if (viewSettings.collapsed) { - if (UM.SimulationView.compatibilityMode) { + if (viewSettings.collapsed) + { + if (UM.SimulationView.compatibilityMode) + { return UM.Theme.getSize("layerview_menu_size_compatibility_collapsed").height; } return UM.Theme.getSize("layerview_menu_size_collapsed").height; - } else if (UM.SimulationView.compatibilityMode) { + } + else if (UM.SimulationView.compatibilityMode) + { return UM.Theme.getSize("layerview_menu_size_compatibility").height; - } else if (UM.Preferences.getValue("layerview/layer_view_type") == 0) { + } + else if (UM.Preferences.getValue("layerview/layer_view_type") == 0) + { return UM.Theme.getSize("layerview_menu_size_material_color_mode").height + UM.SimulationView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height) - } else { + } + else + { return UM.Theme.getSize("layerview_menu_size").height + UM.SimulationView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height) } } Behavior on height { NumberAnimation { duration: 100 } } - property var buttonTarget: { + property var buttonTarget: + { if(parent != null) { var force_binding = parent.y; // ensure this gets reevaluated when the panel moves @@ -44,7 +57,8 @@ Item return Qt.point(0,0) } - Rectangle { + Rectangle + { id: layerViewMenu anchors.right: parent.right anchors.top: parent.top @@ -83,7 +97,8 @@ Item } } - ColumnLayout { + ColumnLayout + { id: viewSettings property bool collapsed: false @@ -195,7 +210,8 @@ Item width: width } - Connections { + Connections + { target: UM.Preferences onPreferenceChanged: { @@ -212,18 +228,22 @@ Item } } - Repeater { + Repeater + { model: Cura.ExtrudersModel{} - CheckBox { + CheckBox + { id: extrudersModelCheckBox checked: viewSettings.extruder_opacities[index] > 0.5 || viewSettings.extruder_opacities[index] == undefined || viewSettings.extruder_opacities[index] == "" - onClicked: { + onClicked: + { viewSettings.extruder_opacities[index] = checked ? 1.0 : 0.0 UM.Preferences.setValue("layerview/extruder_opacities", viewSettings.extruder_opacities.join("|")); } visible: !UM.SimulationView.compatibilityMode enabled: index + 1 <= 4 - Rectangle { + Rectangle + { anchors.verticalCenter: parent.verticalCenter anchors.right: extrudersModelCheckBox.right width: UM.Theme.getSize("layerview_legend_size").width @@ -253,8 +273,10 @@ Item } } - Repeater { - model: ListModel { + Repeater + { + model: ListModel + { id: typesLegendModel Component.onCompleted: { @@ -285,13 +307,16 @@ Item } } - CheckBox { + CheckBox + { id: legendModelCheckBox checked: model.initialValue - onClicked: { + onClicked: + { UM.Preferences.setValue(model.preference, checked); } - Rectangle { + Rectangle + { anchors.verticalCenter: parent.verticalCenter anchors.right: legendModelCheckBox.right width: UM.Theme.getSize("layerview_legend_size").width @@ -320,18 +345,22 @@ Item } } - CheckBox { + CheckBox + { checked: viewSettings.only_show_top_layers - onClicked: { + onClicked: + { UM.Preferences.setValue("view/only_show_top_layers", checked ? 1.0 : 0.0); } text: catalog.i18nc("@label", "Only Show Top Layers") visible: UM.SimulationView.compatibilityMode style: UM.Theme.styles.checkbox } - CheckBox { + CheckBox + { checked: viewSettings.top_layer_count == 5 - onClicked: { + onClicked: + { UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1); } text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top") @@ -339,8 +368,10 @@ Item style: UM.Theme.styles.checkbox } - Repeater { - model: ListModel { + Repeater + { + model: ListModel + { id: typesLegendModelNoCheck Component.onCompleted: { @@ -355,11 +386,13 @@ Item } } - Label { + Label + { text: label visible: viewSettings.show_legend id: typesLegendModelLabel - Rectangle { + Rectangle + { anchors.verticalCenter: parent.verticalCenter anchors.right: typesLegendModelLabel.right width: UM.Theme.getSize("layerview_legend_size").width @@ -378,30 +411,37 @@ Item } // Text for the minimum, maximum and units for the feedrates and layer thickness - Item { + Item + { id: gradientLegend visible: viewSettings.show_gradient width: parent.width height: UM.Theme.getSize("layerview_row").height - anchors { + anchors + { topMargin: UM.Theme.getSize("slider_layerview_margin").height horizontalCenter: parent.horizontalCenter } - Label { + Label + { text: minText() anchors.left: parent.left color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") - function minText() { - if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { + function minText() + { + if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) + { // Feedrate selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 2) { + if (UM.Preferences.getValue("layerview/layer_view_type") == 2) + { return parseFloat(UM.SimulationView.getMinFeedrate()).toFixed(2) } // Layer thickness selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 3) { + if (UM.Preferences.getValue("layerview/layer_view_type") == 3) + { return parseFloat(UM.SimulationView.getMinThickness()).toFixed(2) } } @@ -409,20 +449,25 @@ Item } } - Label { + Label + { text: unitsText() anchors.horizontalCenter: parent.horizontalCenter color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") - function unitsText() { - if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { + function unitsText() + { + if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) + { // Feedrate selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 2) { + if (UM.Preferences.getValue("layerview/layer_view_type") == 2) + { return "mm/s" } // Layer thickness selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 3) { + if (UM.Preferences.getValue("layerview/layer_view_type") == 3) + { return "mm" } } @@ -430,20 +475,25 @@ Item } } - Label { + Label + { text: maxText() anchors.right: parent.right color: UM.Theme.getColor("setting_control_text") font: UM.Theme.getFont("default") - function maxText() { - if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) { + function maxText() + { + if (UM.SimulationView.layerActivity && CuraApplication.platformActivity) + { // Feedrate selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 2) { + if (UM.Preferences.getValue("layerview/layer_view_type") == 2) + { return parseFloat(UM.SimulationView.getMaxFeedrate()).toFixed(2) } // Layer thickness selected - if (UM.Preferences.getValue("layerview/layer_view_type") == 3) { + if (UM.Preferences.getValue("layerview/layer_view_type") == 3) + { return parseFloat(UM.SimulationView.getMaxThickness()).toFixed(2) } } @@ -453,7 +503,8 @@ Item } // Gradient colors for feedrate - Rectangle { // In QML 5.9 can be changed by LinearGradient + Rectangle + { // In QML 5.9 can be changed by LinearGradient // Invert values because then the bar is rotated 90 degrees id: feedrateGradient visible: viewSettings.show_feedrate_gradient @@ -463,20 +514,25 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") transform: Rotation {origin.x: 0; origin.y: 0; angle: 90} - gradient: Gradient { - GradientStop { + gradient: Gradient + { + GradientStop + { position: 0.000 color: Qt.rgba(1, 0.5, 0, 1) } - GradientStop { + GradientStop + { position: 0.625 color: Qt.rgba(0.375, 0.5, 0, 1) } - GradientStop { + GradientStop + { position: 0.75 color: Qt.rgba(0.25, 1, 0, 1) } - GradientStop { + GradientStop + { position: 1.0 color: Qt.rgba(0, 0, 1, 1) } @@ -484,7 +540,8 @@ Item } // Gradient colors for layer thickness (similar to parula colormap) - Rectangle { // In QML 5.9 can be changed by LinearGradient + Rectangle // In QML 5.9 can be changed by LinearGradient + { // Invert values because then the bar is rotated 90 degrees id: thicknessGradient visible: viewSettings.show_thickness_gradient @@ -494,24 +551,30 @@ Item border.width: UM.Theme.getSize("default_lining").width border.color: UM.Theme.getColor("lining") transform: Rotation {origin.x: 0; origin.y: 0; angle: 90} - gradient: Gradient { - GradientStop { + gradient: Gradient + { + GradientStop + { position: 0.000 color: Qt.rgba(1, 1, 0, 1) } - GradientStop { + GradientStop + { position: 0.25 color: Qt.rgba(1, 0.75, 0.25, 1) } - GradientStop { + GradientStop + { position: 0.5 color: Qt.rgba(0, 0.75, 0.5, 1) } - GradientStop { + GradientStop + { position: 0.75 color: Qt.rgba(0, 0.375, 0.75, 1) } - GradientStop { + GradientStop + { position: 1.0 color: Qt.rgba(0, 0, 0.5, 1) } @@ -520,19 +583,22 @@ Item } } - Item { + Item + { id: slidersBox width: parent.width visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity - anchors { + anchors + { top: parent.bottom topMargin: UM.Theme.getSize("slider_layerview_margin").height left: parent.left } - PathSlider { + PathSlider + { id: pathSlider height: UM.Theme.getSize("slider_handle").width @@ -553,25 +619,29 @@ Item rangeColor: UM.Theme.getColor("slider_groove_fill") // update values when layer data changes - Connections { + Connections + { target: UM.SimulationView onMaxPathsChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) onCurrentPathChanged: pathSlider.setHandleValue(UM.SimulationView.currentPath) } // make sure the slider handlers show the correct value after switching views - Component.onCompleted: { + Component.onCompleted: + { pathSlider.setHandleValue(UM.SimulationView.currentPath) } } - LayerSlider { + LayerSlider + { id: layerSlider width: UM.Theme.getSize("slider_handle").width height: UM.Theme.getSize("layerview_menu_size").height - anchors { + anchors + { top: !UM.SimulationView.compatibilityMode ? pathSlider.bottom : parent.top topMargin: !UM.SimulationView.compatibilityMode ? UM.Theme.getSize("default_margin").height : 0 right: parent.right @@ -593,7 +663,8 @@ Item handleLabelWidth: UM.Theme.getSize("slider_layerview_background").width // update values when layer data changes - Connections { + Connections + { target: UM.SimulationView onMaxLayersChanged: layerSlider.setUpperValue(UM.SimulationView.currentLayer) onMinimumLayerChanged: layerSlider.setLowerValue(UM.SimulationView.minimumLayer) @@ -601,45 +672,54 @@ Item } // make sure the slider handlers show the correct value after switching views - Component.onCompleted: { + Component.onCompleted: + { layerSlider.setLowerValue(UM.SimulationView.minimumLayer) layerSlider.setUpperValue(UM.SimulationView.currentLayer) } } // Play simulation button - Button { + Button + { id: playButton iconSource: "./resources/simulation_resume.svg" style: UM.Theme.styles.small_tool_button visible: !UM.SimulationView.compatibilityMode - anchors { + anchors + { verticalCenter: pathSlider.verticalCenter } property var status: 0 // indicates if it's stopped (0) or playing (1) - onClicked: { - switch(status) { - case 0: { + onClicked: + { + switch(status) + { + case 0: + { resumeSimulation() break } - case 1: { + case 1: + { pauseSimulation() break } } } - function pauseSimulation() { + function pauseSimulation() + { UM.SimulationView.setSimulationRunning(false) iconSource = "./resources/simulation_resume.svg" simulationTimer.stop() status = 0 } - function resumeSimulation() { + function resumeSimulation() + { UM.SimulationView.setSimulationRunning(true) iconSource = "./resources/simulation_pause.svg" simulationTimer.start() @@ -652,7 +732,8 @@ Item interval: 100 running: false repeat: true - onTriggered: { + onTriggered: + { var currentPath = UM.SimulationView.currentPath var numPaths = UM.SimulationView.numPaths var currentLayer = UM.SimulationView.currentLayer @@ -697,7 +778,8 @@ Item } } - FontMetrics { + FontMetrics + { id: fontMetrics font: UM.Theme.getFont("default") }